hdu2845: Beans

hdu2845: http://acm.hdu.edu.cn/showproblem.php?pid=2845
题意:吃豆:如果吃了某个豆(x,y),则x-1和x+1两行都不能吃,(x,y-1)、(x,y+1)也不能吃,求最多能吃多少豆 解法:dp:先算行,再算列,列的算法和行的类似,dp[i][j]表示在第i行中,直到第(i,j)个点的最优值,有状态转移方程:dp[i][j]=max(dp[i][j-1],dp[i][j-2]+v[i][j]),再计算列的,方程类似,为dp1[i]=max(dp1[i-1],dp1[i-2]+dp[i][n-1]).
code:
#include<iostream>
#include<cstdio>
#include<cstdlib>
int max(int a,int b)
{
    if(a>b)
        return a;
    else
        return b;
}
int *v[200001],*dp[200001],*dp1;
int main()
{
    int m,n,i,j;
    scanf("%d%d",&m,&n);
    for(i=0;i<m+10;i++)                 //申请内存,否则会爆
        v[i]=(int *)malloc(sizeof(int)*(n+10));
    for(i=0;i<m+10;i++)
        dp[i]=(int *)malloc(sizeof(int)*(n+10));
    dp1=(int *)malloc((m+10)*sizeof(int));
    for(i=0;i<m;i++)
        for(j=0;j<n;j++)
        {
            scanf("%d",&v[i][j]);
            if(j==0||j==1)
                dp[i][j]=v[i][j];    //起点可能是每行的第一个或者第二个
        }
    for(i=0;i<m;i++)
    {
        for(j=2;j<n;j++)
        {
            dp[i][j]=max(dp[i][j-1],dp[i][j-2]+v[i][j]);    //要么吃了前一个,这个不吃,要么吃了之前的第二个,再吃这个
        }
        if(i==0||i==1)         //类似行的计算,列的起点可能是第一列或第二列
        dp1[i]=dp[i][n-1];
        free(v[i]);
    }
    for(i=2;i<m;i++)
    {
        dp1[i]=max(dp1[i-1],dp1[i-2]+dp[i][n-1]);     //类似行的计算
    }
    for(i=0;i<m;i++)
    {
        free(dp[i]);
    }
    printf("%d\n",dp1[m-1]);
    free(dp1);
}
/*
input:
4 6
11 0 7 5 13 9
78 4 81 6 22 4
1 40 9 34 16 10
11 22 0 33 39 6
ouput:
242
*/

posted on 2012-07-25 15:24  acmer-jun  阅读(175)  评论(0编辑  收藏  举报

导航