開四維數組肯定超出內存限制和時間限制的,這裏要聯繫到如果知道塗上了紅色多少,就可以計算出綠色,這樣狀態的維數就減少了
狀態dp[x][y][z] 表示前x個,紅色的面積爲y,第x個顏色爲z
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define RED 0
#define COLOR 2
#define MAXN 201
#define MAXV 40001
#define INF 0x3f3f3f3f
int f[MAXN][MAXV][COLOR], h[MAXN], sum[MAXN];
int main(int argc, char const *argv[])
{
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n, area[COLOR], rst; sum[0] = h[0] = 0;
while( ~scanf("%d %d %d", &n, &area[0], &area[1]) ) {
for(int i = 1; i <= n; i ++) {
scanf("%d", &h[i]); sum[i] = sum[i-1]+h[i];
}
if( 1 == n ) {
if( area[0] < h[1] && area[1] < h[1] ) {
printf("-1\n"); continue;
}
printf("0\n");
}
memset(f, 0x3F, sizeof(f));
if( area[!RED] >= h[1] ) {
f[1][0][!RED] = 0;
}
if( area[RED] >= h[1] ) {
f[1][0][RED] = 0;
}
for(int i = 1; i <= n; i ++) {
for(int j = 0; j <= sum[i-1]; j ++) {
if( area[RED]-j >= h[i] ) {
f[i][j][RED] = min(f[i][j][RED], f[i-1][j][!RED]+min(h[i], h[i-1]));
f[i][j][RED] = min(f[i][j][RED], f[i-1][j-h[i-1]][RED]);
}
if( area[!RED]-sum[i-1]+j >= h[i] ) {
f[i][j][!RED] = min(f[i][j][!RED], f[i-1][j][!RED]);
f[i][j][!RED] = min(f[i][j][!RED], f[i-1][j-h[i-1]][RED]+min(h[i], h[i-1]));
}
}
}
rst = INF;
for(int i = 0; i <= sum[n]; i ++) {
rst = min(rst, min(f[n][i][!RED], f[n][i][RED]));
}
if( INF == rst ) {
printf("-1\n"); continue;
}
printf("%d\n", rst);
}
return 0;
}