题意:一个宽为2长为n的画廊,每个格子有一个值,问你关闭k个格子,使得画廊不堵塞且剩余值最大。
解题思路:dp[i][j][0/1] 表示 第 i个位置 ,选取第 j个格子关闭 ,关闭i位置的k格子的最小值。
解题代码:
1 // File Name: h.cpp 2 // Author: darkdream 3 // Created Time: 2015年03月14日 星期六 12时28分16秒 4 5 #include<vector> 6 #include<list> 7 #include<map> 8 #include<set> 9 #include<deque> 10 #include<stack> 11 #include<bitset> 12 #include<algorithm> 13 #include<functional> 14 #include<numeric> 15 #include<utility> 16 #include<sstream> 17 #include<iostream> 18 #include<iomanip> 19 #include<cstdio> 20 #include<cmath> 21 #include<cstdlib> 22 #include<cstring> 23 #include<ctime> 24 #define LL long long 25 26 using namespace std; 27 int a[300][3]; 28 int dp[300][300][3]; 29 void update(int i , int j , int k ,int val,int plus) 30 { 31 if(val == -1) 32 return; 33 if(dp[i][j][k] == -1) 34 dp[i][j][k] = val+plus ; 35 else dp[i][j][k] = min(dp[i][j][k],val+ plus); 36 } 37 int main(){ 38 int n , m ; 39 while(scanf("%d %d",&n,&m) != EOF) 40 { 41 if(n == 0 && m == 0 ) 42 break; 43 int sum = 0; 44 for(int i = 1;i <= n;i ++) 45 { 46 scanf("%d %d",&a[i][0],&a[i][1]); 47 sum += a[i][0]+a[i][1]; 48 } 49 int ans = 1e9; 50 if(m == 0 ) 51 { 52 printf("%d ",sum); 53 continue; 54 } 55 memset(dp,-1,sizeof(dp)); 56 dp[0][0][0] = 0 ; 57 dp[0][0][1] = 0 ; 58 for(int i= 1;i <= n;i ++) 59 { 60 for(int j = 1;j <= m;j++) 61 { 62 update(i,j,0,dp[i-1][j-1][0],a[i][0]); 63 update(i,j,1,dp[i-1][j-1][1],a[i][1]); 64 65 for(int s = 0 ;s < i-1 ;s ++ ) 66 { 67 update(i,j,0,dp[s][j-1][0],a[i][0]); 68 update(i,j,0,dp[s][j-1][1],a[i][0]); 69 update(i,j,1,dp[s][j-1][0],a[i][1]); 70 update(i,j,1,dp[s][j-1][1],a[i][1]); 71 } 72 } 73 /*for(int j = 0 ;j <= m;j ++) 74 { 75 printf("%d %d ",dp[i][j][0],dp[i][j][1]); 76 } 77 printf("*** ");*/ 78 if(dp[i][m][0] != -1) 79 ans = min(ans,dp[i][m][0]); 80 if(dp[i][m][1] != -1) 81 ans = min(ans,dp[i][m][1]); 82 } 83 printf("%d ",sum-ans); 84 } 85 return 0; 86 }