BZOJ2748
-
题目
-
分析
考虑 D P DP DP
f [ i ] [ j ] f[i][j] f[i][j] 表示音量为 j j j 可以由前 i i i 次增加或减少构成
f [ i ] [ j ] = 1 ( f [ i − 1 ] [ j + a [ i ] ] = 1 ∣ ∣ f [ i − 1 ] [ j − a [ i ] ] = 1 ) f[i][j] = 1 \qquad (f[i - 1][j + a[i]] = 1 || f[i - 1][j - a[i]] = 1) f[i][j]=1(f[i−1][j+a[i]]=1∣∣f[i−1][j−a[i]]=1)
if (j + a[i] <= ml && f[i - 1][j + a[i]]) // 前i次变换后减a[i]得到f[i][j] f[i][j] = 1; if (j - a[i] >= 0 && f[i - 1][j - a[i]])//前i次变换后加a[i]得到f[i][j] f[i][j] = 1;
-
代码
const int N = 55; int a[N]; int f[N][1005]; int main () { //freopen("input.in", "r", stdin); //freopen("test.out", "w", stdout); int n, bl, ml; read(n); read(bl); read(ml); for (int i = 1; i <= n; i++) read(a[i]); memset(f, 0, sizeof(f)); f[0][bl] = 1; for (int i = 1; i <= n; i++) { for (int j = 0; j <= ml; j++) { if (j + a[i] <= ml && f[i - 1][j + a[i]]) f[i][j] = 1; if (j - a[i] >= 0 && f[i - 1][j - a[i]]) f[i][j] = 1; } } int ans = 0; for (int i = ml; i >= 0; i--) if (f[n][i]) {ans = i; break;} if (ans) cout << ans << endl; else cout << -1 << endl; return 0; }
-
题型
D P DP DP