HDU 5234 Happy birthday 01背包
题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5234
bc:http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=585&pid=1003
题解:
由于数据比较小,所以可以转化为判定性问题,即:
dp[i][j][kk]表示走到i,j这一点时吃了kk重的蛋糕,转移方程只要考虑这一点的蛋糕吃和不吃两种情况(01背包)
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 6 const int maxn=111; 7 8 bool dp[maxn][maxn][maxn]; 9 int arr[maxn][maxn]; 10 int n,m,kilo; 11 12 void init(){ 13 memset(dp,0,sizeof(dp)); 14 for(int i=0;i<maxn;i++){ 15 for(int j=0;j<maxn;j++){ 16 dp[i][j][0]=1; 17 } 18 } 19 } 20 21 int main(){ 22 while(scanf("%d%d%d",&n,&m,&kilo)==3&&n){ 23 init(); 24 for(int i=1;i<=n;i++){ 25 for(int j=1;j<=m;j++){ 26 scanf("%d",&arr[i][j]); 27 } 28 } 29 30 for(int i=1;i<=n;i++){ 31 for(int j=1;j<=m;j++){ 32 for(int k=1;k<=kilo;k++){ 33 //(i,j)这点的蛋糕不吃 34 dp[i][j][k]=dp[i-1][j][k]|dp[i][j-1][k]; 35 //(i,j)吃这点的蛋糕 36 if(k>=arr[i][j]){ 37 dp[i][j][k]|=dp[i-1][j][k-arr[i][j]]; 38 dp[i][j][k]|=dp[i][j-1][k-arr[i][j]]; 39 } 40 } 41 } 42 } 43 44 int ans=0; 45 for(int i=kilo;i>=0;i--){ 46 if(dp[n][m][i]){ 47 ans=i; break; 48 } 49 } 50 printf("%d\n",ans); 51 } 52 return 0; 53 }