hdu1565 方格取数(1)(状压dp)

来源:互联网 发布:51单片机操作系统 编辑:程序博客网 时间:2024/06/04 19:38

可以状压搞,因为n很小,虽说复杂度到了4亿,但是数据确实水。

#include <bits/stdc++.h>using namespace std;const int MAXN = 20+5;int n;int tu[MAXN][MAXN];int dp[2][1<<20];void get_dp(){    //记录两行的状态,每次枚举每一行的格点    for(int i = 0; i < n; ++i)        for(int j = 0; j < n; ++j)        {            //枚举第j个            int t = 1<<j;            //按照行的奇偶性,分开            int p = (i*n+j)%2;            //枚举上一行的状态            for(int state = 0; state < (1<<n); ++state)            {                //如果当前的位置j没有选,那么左右没有影响,上面可选  可    不选。                if((state & t) == 0)dp[!p][state] = max(dp[p][state+t],dp[p][state]);                //如果当前位置j选了,并且j-1也选了,那么不符合条件                else if(j && (state & (t>>1)))dp[!p][state] = 0;//这里踩坑(state & (t>>1))不是等于1而是要大于0                //当前j选了但是符合条件的情况,那么上面不能选                else dp[!p][state] = dp[p][state-t] + tu[i][j];            }        }}int main(){    while(~scanf("%d",&n))    {        for(int i = 0; i < n; ++i)            for(int j = 0; j < n; ++j)scanf("%d",&tu[i][j]);        memset(dp,0,sizeof dp);        get_dp();        int MAX = 0;        int p = n*n%2;        for(int i = 0; i < (1<<n); ++i)MAX = max(MAX,dp[p][i]);        printf("%d\n",MAX);    }    return 0;}


原创粉丝点击