Advertisement
a53

dragonfruit

a53
Sep 23rd, 2022
168
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.71 KB | None | 0 0
  1. #include<fstream>
  2. #include<cstring>
  3. using namespace std;
  4.  
  5. ifstream fin("dragonfruit.in");
  6. ofstream fout("dragonfruit.out");
  7.  
  8. const int SMAX = 11;
  9. const int KMAX = 1e3 + 1;
  10. const int MOD = 1e9 + 7;
  11. const int INF = 1e9;
  12. const int NMAX = 1e5 + 1;
  13.  
  14. struct sol
  15. {
  16. int cactusi = INF,moduri = 0;
  17. };
  18.  
  19. sol vechi[SMAX][KMAX][2],nou[SMAX][KMAX][2],initial[SMAX][KMAX][2];
  20.  
  21. int v[NMAX];
  22.  
  23. // daca subsecventa e deschisa avem 1,daca nu avem 0
  24.  
  25. int s,k;
  26.  
  27.  
  28. sol update(sol a,sol b)
  29. {
  30. if(a.cactusi ^ b.cactusi)
  31. {
  32. if(a.cactusi > b.cactusi)
  33. {
  34. return b;
  35. }
  36. else
  37. {
  38. return a;
  39. }
  40. }
  41.  
  42. sol noua = a;
  43. noua.moduri += b.moduri;
  44. noua.moduri = noua.moduri % MOD;
  45.  
  46. return noua;
  47. }
  48.  
  49. void sterge(sol v[][KMAX][2],int n,int m)
  50. {
  51. for(int i = 0 ; i <= n ; i++)
  52. {
  53. for(int j = 0 ; j <= m ; j++)
  54. {
  55. v[i][j][0] = initial[i][j][0];
  56. v[i][j][1] = initial[i][j][1];
  57. }
  58. }
  59. }
  60.  
  61.  
  62. void par(int i)
  63. {
  64. sterge(vechi,s,k);
  65. vechi[0][0][0].moduri = 1;
  66. vechi[0][0][0].cactusi = 0;
  67. for(int e = 1; e <= s; e++)
  68. {
  69. for(int suma = 1 ; suma <= k ; suma++)
  70. {
  71. if(suma >= v[i])
  72. {
  73. //adaug la interval deschis
  74.  
  75. sol f = nou[e][suma - v[i]][1]; f.cactusi++;
  76. vechi[e][suma][1] = update(vechi[e][suma][1],f);
  77.  
  78. // deschid un nou interval
  79.  
  80. f = nou[e - 1][suma - v[i]][0]; f.cactusi++;
  81. vechi[e][suma][1] = update(vechi[e][suma][1],f);
  82.  
  83. f = nou[e - 1][suma - v[i]][1]; f.cactusi++;
  84. vechi[e][suma][1] = update(vechi[e][suma][1],f);
  85. }
  86.  
  87.  
  88. // inchid intervalul curent
  89.  
  90. vechi[e][suma][0] = update(vechi[e][suma][0],nou[e][suma][1]);
  91.  
  92. //pastrez intervalul inchis
  93.  
  94. vechi[e][suma][0] = update(vechi[e][suma][0],nou[e][suma][0]);
  95. }
  96. }
  97. }
  98.  
  99. void impar(int i)
  100. {
  101. sterge(nou,s,k);
  102. nou[0][0][0].moduri = 1;
  103. nou[0][0][0].cactusi = 0;
  104. for(int e = 1; e <= s; e++)
  105. {
  106. for(int suma = 1 ; suma <= k ; suma++)
  107. {
  108. if(suma >= v[i])
  109. {
  110. sol f = vechi[e][suma - v[i]][1]; f.cactusi++;
  111. nou[e][suma][1] = update(nou[e][suma][1],f);
  112.  
  113.  
  114.  
  115. f = vechi[e - 1][suma - v[i]][0]; f.cactusi++;
  116. nou[e][suma][1] = update(nou[e][suma][1],f);
  117.  
  118. f = vechi[e - 1][suma - v[i]][1]; f.cactusi++;
  119. nou[e][suma][1] = update(nou[e][suma][1],f);
  120. }
  121.  
  122.  
  123. nou[e][suma][0] = update(nou[e][suma][0],vechi[e][suma][1]);
  124. nou[e][suma][0] = update(nou[e][suma][0],vechi[e][suma][0]);
  125. }
  126. }
  127. }
  128.  
  129. void rezpar()
  130. {
  131. int cmin = INF;
  132. int moduri = 0;
  133.  
  134. for(int e = 1; e <= s ; e++)
  135. {
  136. if(vechi[e][k][0].moduri)
  137. {
  138. if(vechi[e][k][0].cactusi == cmin){
  139. moduri += vechi[e][k][0].moduri;
  140. if(moduri > MOD)
  141. moduri -= MOD;
  142. }
  143.  
  144. if(vechi[e][k][0].cactusi < cmin)
  145. {
  146. moduri = vechi[e][k][0].moduri;
  147. cmin = vechi[e][k][0].cactusi;
  148. }
  149. }
  150.  
  151. if(vechi[e][k][1].moduri)
  152. {
  153. if(vechi[e][k][1].cactusi == cmin){
  154. moduri += vechi[e][k][1].moduri;
  155. if(moduri > MOD)
  156. moduri -= MOD;
  157. }
  158.  
  159. if(vechi[e][k][1].cactusi < cmin)
  160. {
  161. moduri = vechi[e][k][1].moduri;
  162. cmin = vechi[e][k][1].cactusi;
  163. }
  164. }
  165. }
  166.  
  167. int st = cmin ^ INF ? cmin : 0;
  168. fout << st << " " << moduri << '\n';
  169. }
  170.  
  171. void rezimpar()
  172. {
  173. int cmin = INF;
  174. int moduri = 0;
  175.  
  176. for(int e = 1; e <= s ; e++)
  177. {
  178. if(nou[e][k][0].moduri)
  179. {
  180. if(nou[e][k][0].cactusi == cmin){
  181. moduri += nou[e][k][0].moduri;
  182. if(moduri > MOD)
  183. moduri -= MOD;
  184. }
  185.  
  186. if(nou[e][k][0].cactusi < cmin)
  187. {
  188. moduri = nou[e][k][0].moduri;
  189. cmin = nou[e][k][0].cactusi;
  190. }
  191. }
  192.  
  193. if(nou[e][k][1].moduri)
  194. {
  195. if(nou[e][k][1].cactusi == cmin){
  196. moduri += nou[e][k][1].moduri;
  197. if(moduri > MOD)
  198. moduri -= MOD;
  199. }
  200. if(nou[e][k][1].cactusi < cmin)
  201. {
  202. moduri = nou[e][k][1].moduri;
  203. cmin = nou[e][k][1].cactusi;
  204. }
  205. }
  206. }
  207.  
  208. int st = cmin ^ INF ? cmin : 0;
  209. fout << st << " " << moduri << '\n';
  210. }
  211.  
  212. void testcase()
  213. {
  214. int n;
  215. fin >> n >> k >> s;
  216.  
  217. for(int i = 1; i <= n ; i++)
  218. {
  219. fin >> v[i];
  220. }
  221.  
  222. sterge(vechi,s,k);
  223.  
  224. // caz de baza
  225.  
  226. vechi[0][0][0].cactusi = 0;
  227. vechi[0][0][0].moduri = 1;
  228.  
  229. for(int i = 1; i <= n ; i++)
  230. {
  231. if(i & 1)
  232. {
  233. impar(i);
  234. }
  235. else
  236. {
  237. par(i);
  238. }
  239. }
  240.  
  241. if(n & 1)
  242. {
  243. rezimpar();
  244. }
  245. else
  246. {
  247. rezpar();
  248. }
  249.  
  250. }
  251.  
  252. int main()
  253. {
  254. int t;
  255. fin >> t;
  256. while(t--)
  257. testcase();
  258.  
  259. fin.close();
  260. fout.close();
  261. return 0; // superpeace
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement