hdu1565 轮廓线动态规划

来源:互联网 发布:linux mysql开机自启 编辑:程序博客网 时间:2024/06/05 22:10

也是比较经典的轮廓线动态规划问题,每一个格子可以放或者不放,0和1表示,那么就是判断上一个状态的左边和上边是否已经选了,注意一下列首的时候不用判断前一个是否放了,有一个地方要注意一下,因为对于每一个状态 枚举的时候可能枚举到不符合要求的状态,如果判断单独来判断该状态是否符合规范 比较麻烦 因为首列的两个1可以并列,所以比较麻烦,这里的处理办法就是初始化为-1,更新了的状态肯定是符合要求的那么对于上一个状态如果是-1 那么就不要更新
代码:

#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>#include<string>#include<set>#include<map>#include<queue>#include<stack>#include<cstring>using namespace std;#define LL long longLL dp[2][1<<20];int main(){    int n;    while(scanf("%d",&n) != EOF)    {        LL mp[25][25];        memset(dp,-1,sizeof(dp));        for(int i = 0;i<n;i++)        {            for(int j = 0;j<n;j++)            {                scanf("%lld",&mp[i][j]);            }        }        dp[0][0] = 0;        int cur = 0;        for(int i = 0;i<n;i++)        {            for(int j = 0;j<n;j++)            {                for(int k = 0;k<(1<<n);k++)                {                    if(dp[cur][k]<0)continue;                    // 放                    if((j==0 || (k&1)==0) && (k&(1<<(n-1)))==0)                    {                        dp[1-cur][(k<<1)|1] = max(dp[1-cur][(k<<1)|1],dp[cur][k]+mp[i][j]);                    }                    // 不放                    dp[1-cur][(k<<1) & (1<<n)-1] = max(dp[1-cur][(k<<1) & (1<<n)-1],dp[cur][k]);                }                memset(dp[cur],-1,sizeof(dp[cur]));                cur = cur^1;            }        }        LL ans = 0;        for(int i = 0;i<(1<<n);i++)        {            ans = max(ans,dp[cur][i]);        }        printf("%lld\n",ans);    }    return 0;}
原创粉丝点击