joj 2620: Count Square 状态压缩DP N*M的0,1方格,每一个2*2的小方格有一个价值,求整个方格的最大价值

Xiaoming is a 5-year old boy. He has many toys. Among them there is a magic box. On the top of the box there are n * m grids. One can color the grids into black or white. The box won't open unless the value of the grids is maximal. you are to calculate the maximal value. The value of the grids is defined as follow: Every 2*2 grids formed a big square. That's amazing, isn't it? The 2*2 square has its value according to its color. You find all different 2*2 grids in the grids and sum up their values. The 2*2 grids are consider different if their locations are different. For example in a 3 * 5 grids you can find 8 different 2*2 grids. Values of 2*2 grids of different color are given. The rest are considered zero. Now given n, m and the values of 2*2 grids according to their color.

Input

n, m (n <= 1000, m <= 6) a number t 2*2 grids given next 3*t lines 2 lines each line 2 char present the 2*2 grids ( b present black & w present white, no extra space), eg. bb ww then a value

Output

maximal value

Sample Input

5 2
2
bb
bb
5
ww
ww
0

Sample Output

20

 

 //

 

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
int tlv[100][100];//两行状态的最大值
int val[10][10];//小方格第一行,第二行的状态
int dp[2][100];//到第i行j状态时的最大值
int main()
{
    int hash[130];hash['b']=0,hash['w']=1;
    while(scanf("%d%d",&n,&m)==2)
    {
        memset(val,0,sizeof(val));
        int t;scanf("%d",&t);
        while(t--)
        {
            char str[4];
            scanf("%s",str);
            int u=hash[str[0]]*2+hash[str[1]];
            scanf("%s",str);
            int v=hash[str[0]]*2+hash[str[1]];
            scanf("%d",&val[u][v]);
        }
        int maxState=1<<m;
        memset(tlv,0,sizeof(tlv));
        for(int i=0;i<maxState;i++)//pre
        {
            for(int j=0;j<maxState;j++)//cur
            {
                for(int k=1;k<m;k++)
                {
                    int l=m-k-1;
                    tlv[i][j]+=val[(i>>l)&3][(j>>l)&3];
                }
            }
        }
        memset(dp,0,sizeof(dp));
        //初始化第2行
        for(int i=0;i<maxState;i++)//cur
        {
            for(int j=0;j<maxState;j++)//pre
            {
                dp[0][i]=max(dp[0][i],tlv[j][i]);
            }
        }
        for(int r=3;r<=n;r++)
        {
            int cur=r&1;
            for(int i=0;i<maxState;i++)//cur
            {
                for(int j=0;j<maxState;j++)//pre
                {
                    dp[cur][i]=max(dp[cur][i],dp[!cur][j]+tlv[j][i]);
                }
            }
        }
        int ans=0;
        for(int i=0;i<maxState;i++)
        {
            ans=max(ans,dp[n&1][i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值