解題思路:dp[i][j]代表到第i行的第j個狀態所能得到的最大的和,可以先處理一行沒有兩個相鄰的滿足條件的狀態。然後把每行每個狀態的和都算出來,狀態轉移的條件是當前這行第j個狀態與上一行的第k個狀態想與為0,即沒有相鄰的,那就能更新dp[i][j]:dp[i][j]=max(dp[i][j],dp[i-1][k]+sum[i][j]);還有乙個就是n為20的最大情況數,不能直接1<<20這樣會爆記憶體,不曉得怎麼用數學直接算出來了,那就只能暴力一下了,在17000+,開20000或者1<<15都夠了。
#include#define il inline
#define pb push_back
#define fi first
#define se second
#define ms(_data,v) memset(_data,v,sizeof(_data))
#define sc(n) scanf("%d",&n)
#define sc(n,m) scanf("%d %d",&n,&m)
#define sz(a) int((a).size())
#define rep(i,a,b) for(int i=a;i<=b;++i)
using namespace std;
typedef long long ll;
const ll inf=0x3f3f3f3f;
const double pi=acos(-1.0);
const double eps=1e-9;
const int maxn=1<<15;
int n,mp[21][21];
int dp[21][maxn],sum[21][maxn];
int sta[maxn]; //記錄所有可能的狀態
il int cal(int id,int state)
return sum;
}int main()
for(int i=0; i} for(int i=0; ifor(int i=1; i}
}} int ans=0;
for(int i=0; icout<} return 0;
}
HDU 1565 方格取數 1 (狀壓DP)
problem description 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數。從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。input 包括多個測試例項,每個測試例項包括乙個整數n 和n n個非負數 n 20 ou...
HDU 1565 方格取數 1 狀壓DP
description 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數。從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大。input 包括多個測試例項,每個測試例項包括乙個整數n 和n n個非負數 n 20 output 對於每...
HDU 1565 方格取數 1
hdu 1565 方格取數 1 我的第乙個狀態壓縮dp 給你乙個n n的格仔的棋盤,每個格仔裡面有乙個非負數,從中取出若干個數,使得任意的兩個數所在的格仔沒有公共邊,就是說所取的數所在的2個格仔不能相鄰,並且取出的數的和最大 3 75 15 21 75 15 28 34 70 5 188對於每乙個數...