[关闭]
@ljt12138 2017-06-10T17:13:03.000000Z 字数 1996 阅读 860

Codeforces #417(Div 2)


B. Sagheer, the Hausmeister

dp&分类讨论

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int n, m;
  4. char str[17][305];
  5. int lft[17], rgt[17];
  6. int dp[17][2];
  7. int main()
  8. {
  9. memset(dp, -1, sizeof dp);
  10. scanf("%d%d", &n, &m), m += 2;
  11. int beg = -1;
  12. for (int i = 1; i <= n; i++) {
  13. scanf("%s", str[i]+1);
  14. lft[i] = rgt[i] = -1;
  15. for (int j = 1; j <= m; j++) {
  16. if (lft[i] == -1 && str[i][j] == '1') lft[i] = j;
  17. if ( str[i][j] == '1') rgt[i] = j;
  18. }
  19. if (lft[i] != -1) beg = 1;
  20. //cout << lft[i] << " " << rgt[i] << endl;
  21. }
  22. int bg = 1;
  23. while (lft[bg] == -1 && bg <= n) bg++;
  24. if (bg > n) { puts("0"); return 0; }
  25. dp[bg][0] = rgt[bg]-1, dp[bg][1] = m-lft[bg];
  26. // cout << dp[1][0] << " " << dp[1][1] << endl;
  27. for (int i = bg+1; i <= n; i++) {
  28. for (int j = 0; j <= 1; j++) {
  29. dp[i][j] = 23333333;
  30. int adi = 0;
  31. if (lft[i] == -1) adi = 0;
  32. else if (j == 0) adi = (rgt[i]-1)*2;
  33. else adi = (m-lft[i])*2;
  34. for (int k = 0; k <= 1; k++) {
  35. if (j != k) dp[i][j] = min(dp[i][j], dp[i-1][k]+m);
  36. else dp[i][j] = min(dp[i][j], dp[i-1][k]+adi+1);
  37. }
  38. // cout << dp[i][j] << " ";
  39. }
  40. // cout << endl;
  41. }
  42. cout << dp[n][0] << endl;
  43. return 0;
  44. }

C. Sagheer and Nubian Market

二分/枚举k,然后排序...

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 100005;
  4. int A[MAXN], C[MAXN], n, S;
  5. int main()
  6. {
  7. scanf("%d%d", &n, &S);
  8. for (int i = 1; i <= n; i++)
  9. scanf("%d", &A[i]);
  10. int ans = 0, ct = INT_MAX;
  11. for (int k = 1; (long long)k*(k+1)*k/2 <= S && k <= n; k++) {
  12. for (int i = 1; i <= n; i++) {
  13. if (A[i]+1ll*i*k <= S)
  14. C[i] = A[i]+i*k;
  15. else C[i] = S+1;
  16. }
  17. sort(C+1, C+n+1);
  18. int cnt = 0, mon = 0, i = 1;
  19. while (cnt < k && mon+C[i] <= S && i <= n)
  20. mon += C[i], cnt++, i++;
  21. if (cnt == k) {
  22. if (cnt > ans)
  23. ans = cnt, ct = mon;
  24. else if (cnt == ans)
  25. ct = min(ct, mon);
  26. }
  27. }
  28. if (ans == 0) { printf("0 0"); }
  29. else printf("%d %d\n", ans, ct);
  30. return 0;
  31. }

E. Sagheer and Apple Tree

阶梯博弈...只有(从叶子算第一层起)奇数层有影响。分类讨论换奇数/奇数,奇数/偶数和偶数/偶数。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. const int MAXN = 100005;
  4. int A[MAXN], C[MAXN], n, S;
  5. int main()
  6. {
  7. scanf("%d%d", &n, &S);
  8. for (int i = 1; i <= n; i++)
  9. scanf("%d", &A[i]);
  10. int ans = 0, ct = INT_MAX;
  11. for (int k = 1; (long long)k*(k+1)*k/2 <= S && k <= n; k++) {
  12. for (int i = 1; i <= n; i++) {
  13. if (A[i]+1ll*i*k <= S)
  14. C[i] = A[i]+i*k;
  15. else C[i] = S+1;
  16. }
  17. sort(C+1, C+n+1);
  18. int cnt = 0, mon = 0, i = 1;
  19. while (cnt < k && mon+C[i] <= S && i <= n)
  20. mon += C[i], cnt++, i++;
  21. if (cnt == k) {
  22. if (cnt > ans)
  23. ans = cnt, ct = mon;
  24. else if (cnt == ans)
  25. ct = min(ct, mon);
  26. }
  27. }
  28. if (ans == 0) { printf("0 0"); }
  29. else printf("%d %d\n", ans, ct);
  30. return 0;
  31. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注