hdu 1438 鑰匙計數之一狀壓dp(有地方不明白)
阿新 • • 發佈:2018-12-13
Problem Description
一把鎖匙有N個槽,槽深為1,2,3,4。每鎖匙至少有3個不同的深度且至少有1對相連的槽其深度之差為3。求這樣的鎖匙的總數。
Input
本題無輸入
Output
對N>=2且N<=31,輸出滿足要求的鎖匙的總數。
#include<iostream> #include<cstring> using namespace std; const int mm=40; long long dp[mm][mm][mm][2]; ///第幾個槽,前面槽的狀態(包含幾個不同的深度),最後一個槽的深度,是否已經符合要求 int num[17]; int main() { memset(num,0,sizeof(num)); memset(dp,0,sizeof(dp)); for(int i=0; i<16; i++)//2^4次方種狀態; for(int j=0; j<4; j++)//深度個數4個; if(i&(1<<j))num[i]++;///找不同的狀態不同深度數。從而找出合法的至少有3個深度不同 for(int i=0; i<4; i++) ///初始化1只有1,2,3,4四個狀態。 dp[1][1<<i][i][0]=1; for(int i=2; i<32; i++) ///槽數 for(int j=0; j<16; j++) ///不同深度狀態 for(int k=0; k<4; k++) ///前一個槽的最後一個深度 { for(int l=0; l<4; l++) ///當前槽的最後一個的深度 { int cur=j|(1<<l); dp[i][cur][l][1]+=dp[i-1][j][k][1]; if(k-l==3||k-l==-3) { dp[i][cur][l][1]+=dp[i-1][j][k][0]; } else dp[i][cur][l][0]+=dp[i-1][j][k][0]; } } for(int i=2; i<32; i++) { long long ans=0; for(int j=0; j<16; j++) if(num[j]>=3)//挑出符合條件的超過2個不同深度 for(int k=0; k<4; k++) ans+=dp[i][j][k][1]; cout<<"N="<<i<<": "<<ans<<"\n"; } }