hdu1565 方格取数 状压dp

这道题我wa了一下午一晚上

我没看到多组样例!

哦对了初始化的时候是1移位 计算和的时候取位数判断是否为1;

心态爆炸 你说我写错了也好啊 。。。

好吧好吧再接再厉55555555555555

方格取数(1)

Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10629    Accepted Submission(s): 3999


Problem Description
给你一个n*n的格子的棋盘,每个格子里面有一个非负数。
从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取的数所在的2个格子不能相邻,并且取出的数的和最大。
 
Input
包括多个测试实例,每个测试实例包括一个整数n 和n*n个非负数(n<=20)
 
Output
对于每个测试实例,输出可能取得的最大的和
 
Sample Input
3 75 15 21 75 15 28 34 70 5
 
Sample Output
188
 
Author
ailyanlu
 
Source
 
Recommend
8600   |   We have carefully selected several similar problems for you:   1569  1532  3338  1533  1733
 
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int mapp[21][21];
int N,top;
int dp[25][18000],num[25][18000];
int state[18000];

void init0(){
    int maxn = 1<<N;
    for(int i = 0;i < maxn;i++){
        if(!(i&(i<<1)))//修改 
            state[++top] = i; 
    }
}

void init()
{
    top=0;
    int i;
    int total=1<<N;
    for(i=0;i<total;i++)
    {
        if((i&i<<1))
            continue;
        state[++top]=i;
    }
}

int fit(int x,int k){// cm是行 cn是状态数 
    int sum = 0;
    for(int i = 1;i <= N;i++){
        if((x >> (i-1))&1) //修改 
            sum += mapp[k][i];
    }
    return sum;
}

int main(){
    while(scanf("%d",&N) != EOF){
    int i,j,k,z;
    memset(dp,0,sizeof(dp));
    for(i = 1;i <= N;i++){//输入地图 
        for(j = 1;j <= N;j++){
            scanf("%d",&mapp[i][j]);
        }
    }
    init(); //
    for(i = 1;i <= top;i++){//计算每一行每种状态的总值 
        dp[1][i] = num[1][i] = fit(state[i],1);
        for(j = 2;j <= N;j++){
            num[j][i] = fit(state[i],j);
        }
    }

    for(i = 2;i <= N;i++){//枚举1~n-1行 
        for(j = 1;j <= top;j++){//枚举当前行状态
            for(k = 1;k <= top;k++){//枚举上一行状态 
                if(state[j]&state[k])//是否有格子共用一条边 
                    continue;
                dp[i][j] = max(dp[i][j],dp[i-1][k] + num[i][j]);//修护 
            }
        }
    }

    int maxx = -1;
    for(int i = 1;i <= top;i++){
        maxx = max(maxx,dp[N][i]); 
    }
    
    printf("%d\n",maxx);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/xuyanqd/p/9054647.html
今日推荐