@ljt12138
2017-06-10T09:13:03.000000Z
字数 1996
阅读 1021
dp&分类讨论
#include <bits/stdc++.h>using namespace std;int n, m;char str[17][305];int lft[17], rgt[17];int dp[17][2];int main(){memset(dp, -1, sizeof dp);scanf("%d%d", &n, &m), m += 2;int beg = -1;for (int i = 1; i <= n; i++) {scanf("%s", str[i]+1);lft[i] = rgt[i] = -1;for (int j = 1; j <= m; j++) {if (lft[i] == -1 && str[i][j] == '1') lft[i] = j;if ( str[i][j] == '1') rgt[i] = j;}if (lft[i] != -1) beg = 1;//cout << lft[i] << " " << rgt[i] << endl;}int bg = 1;while (lft[bg] == -1 && bg <= n) bg++;if (bg > n) { puts("0"); return 0; }dp[bg][0] = rgt[bg]-1, dp[bg][1] = m-lft[bg];// cout << dp[1][0] << " " << dp[1][1] << endl;for (int i = bg+1; i <= n; i++) {for (int j = 0; j <= 1; j++) {dp[i][j] = 23333333;int adi = 0;if (lft[i] == -1) adi = 0;else if (j == 0) adi = (rgt[i]-1)*2;else adi = (m-lft[i])*2;for (int k = 0; k <= 1; k++) {if (j != k) dp[i][j] = min(dp[i][j], dp[i-1][k]+m);else dp[i][j] = min(dp[i][j], dp[i-1][k]+adi+1);}// cout << dp[i][j] << " ";}// cout << endl;}cout << dp[n][0] << endl;return 0;}
二分/枚举k,然后排序...
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;int A[MAXN], C[MAXN], n, S;int main(){scanf("%d%d", &n, &S);for (int i = 1; i <= n; i++)scanf("%d", &A[i]);int ans = 0, ct = INT_MAX;for (int k = 1; (long long)k*(k+1)*k/2 <= S && k <= n; k++) {for (int i = 1; i <= n; i++) {if (A[i]+1ll*i*k <= S)C[i] = A[i]+i*k;else C[i] = S+1;}sort(C+1, C+n+1);int cnt = 0, mon = 0, i = 1;while (cnt < k && mon+C[i] <= S && i <= n)mon += C[i], cnt++, i++;if (cnt == k) {if (cnt > ans)ans = cnt, ct = mon;else if (cnt == ans)ct = min(ct, mon);}}if (ans == 0) { printf("0 0"); }else printf("%d %d\n", ans, ct);return 0;}
阶梯博弈...只有(从叶子算第一层起)奇数层有影响。分类讨论换奇数/奇数,奇数/偶数和偶数/偶数。
#include <bits/stdc++.h>using namespace std;const int MAXN = 100005;int A[MAXN], C[MAXN], n, S;int main(){scanf("%d%d", &n, &S);for (int i = 1; i <= n; i++)scanf("%d", &A[i]);int ans = 0, ct = INT_MAX;for (int k = 1; (long long)k*(k+1)*k/2 <= S && k <= n; k++) {for (int i = 1; i <= n; i++) {if (A[i]+1ll*i*k <= S)C[i] = A[i]+i*k;else C[i] = S+1;}sort(C+1, C+n+1);int cnt = 0, mon = 0, i = 1;while (cnt < k && mon+C[i] <= S && i <= n)mon += C[i], cnt++, i++;if (cnt == k) {if (cnt > ans)ans = cnt, ct = mon;else if (cnt == ans)ct = min(ct, mon);}}if (ans == 0) { printf("0 0"); }else printf("%d %d\n", ans, ct);return 0;}