protagonist

方格取数(1)

方格取数(1)

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


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
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;
const int maxn = 1e5 + 10;
int n;
int c[26][26];
int dp[maxn],gcur[maxn],gpos[maxn],lans[maxn],lpos[maxn];
int gsize,lsize,cnt;
void dfs(int row,int col,int pos,int val){
    if(col>n){
        gpos[++gsize]=pos;
        gcur[gsize]=val;
        return;
    }
    //cout<<pos<<endl;
    //cout<<(pos|(1<<col))<<endl;
    dfs(row,col+2,pos|(1<<col),val+c[row][col]);
    dfs(row,col+1,pos,val);
}
void solve(){
    for(int i=1;i<=n;++i){
        gsize=0;
        dfs(i,1,0,0);
        for(int j=1;j<=gsize;++j)dp[j]=0;
        for(int j=1;j<=gsize;++j){
            for(int k=1;k<=lsize;++k){
                if(gpos[j]&lpos[k])continue;
                dp[j]=max(dp[j],gcur[j]+lans[k]);
            }
        }
        for(int j=1;j<=gsize;++j){
            lans[j]=dp[j];
            lpos[j]=gpos[j];
        }
        lsize=gsize;
    }
}
int main() {
    //freopen("1.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i=1;i<=n;++i){
            for(int j=1;j<=n;++j){
                scanf("%d",&c[i][j]);
            }
        }
        lpos[1]=0;
        lans[1]=0;
        lsize=1;
        solve();
        int ans=0;
        for(int i=1;i<=lsize;++i){
            ans=max(ans,lans[i]);
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

posted @ 2019-08-01 09:12  czy-power  阅读(496)  评论(0编辑  收藏  举报