题意:
n 块栅栏,宽度均为1 。红色油漆可涂面积 a , 绿色油漆可涂面积 b , 每块栅栏必须且只能涂一种颜色。
对于涂色状态有一个值, 为 每一个 栅栏和他旁边相邻的栅栏如果颜色不同,则该值加上两个栅栏中较低的一个。
求最小值
样例解释:
4 5 7 3 3 4 1
4 块栅栏, 高度分别为 3 3 4 1
5 个单位红油漆, 7 个单位绿油漆
3 3 涂绿油漆 4 1 涂红油漆
这样第二块 和 第三块栅栏颜色不一样。值为 min (3, 4) = 3
答案为 3
思路:
store a three-demensional array [ i ] [ j ] [ k ] , means that for the first i fenses, we use j unit red paint, meanwhile the ith fence is painted as red(if k is 1) or green (is k is 0).
最后:
这题是文件输入,代码里面要把输入输出重定向一下。
1 #include <bits/stdc++.h> 2 3 int dp[200+1][40000+10][2]; 4 int n, a, b; 5 int fen[201]; 6 int s[201]; 7 8 int main() 9 { 10 freopen("input.txt", "r", stdin); 11 freopen("output.txt", "w", stdout); 12 //std::cin >> n >> a >> b; 13 scanf("%d%d%d", &n, &a, &b); 14 s[0] = fen[0] = 0; 15 for(int i = 1; i <= n; ++ i){ 16 //std::cin >> fen[i]; 17 scanf("%d", fen+i); 18 s[i] = s[i-1] + fen[i]; 19 } 20 memset(dp, 0x3f, sizeof dp); 21 dp[0][0][0] = dp[0][0][1] = 0; 22 for(int i = 1; i <= n; ++ i){ 23 for(int j = 0; j <= a; ++ j){ 24 if(dp[i-1][j][1] < 0x3f3f3f3f){ 25 if(fen[i] + j <= a){ 26 dp[i][j+fen[i]][1] = std::min(dp[i][j+fen[i]][1], dp[i-1][j][1]); 27 } 28 if(s[i-1] - j + fen[i] <= b){ 29 dp[i][j][0] = std::min(dp[i][j][0], dp[i-1][j][1] + std::min(fen[i], fen[i-1])); 30 } 31 } 32 if(dp[i-1][j][0] < 0x3f3f3f3f){ 33 if(s[i-1] - j + fen[i] <= b){ 34 dp[i][j][0] = std::min(dp[i][j][0], dp[i-1][j][0]); 35 } 36 if( j + fen[i] <= a){ 37 dp[i][j+fen[i]][1] = std::min(dp[i][j+fen[i]][1], dp[i-1][j][0] + std::min(fen[i], fen[i-1])); 38 } 39 } 40 } 41 } 42 int res = 0x3f3f3f3f; 43 for(int i = 0; i <= a; ++ i){ 44 res = std::min(res, dp[n][i][0]); 45 res = std::min(res, dp[n][i][1]); 46 } 47 if(res == 0x3f3f3f3f){ 48 res = -1; 49 } 50 printf("%d ",res); 51 return 0; 52 53 }