题意:
给出一个只有正负号组成的金字塔,金字塔满足同号的正,异号得负。
例如:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
题解:
dp[i][cnt] opt[i][st] dp表示第i行个数加号个数为cnt的方案数,opt表示第i行状态为st时加号的个数,1表示加号0表示减号,进行状态压缩。最后打表大文件,然后复制粘贴到程序直接输出答案。
打表程序:
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<map> using namespace std; typedef long long ll; const int oo=0x3f3f3f3f; const ll OO=1LL<<61; const ll MOD=1000000007; const int maxn=24; int dp[25][305]; int opt[2][(1<<24)+5]; int bitcount(int st) { return st==0 ? 0 : bitcount(st>>1)+(st&1); } int nextState(int st,int n) { int ans=0,pre,now; for(int i=1;i<n;i++) { pre=st&(1<<(i-1)); now=st&(1<<i); if((pre&&now)||(!pre&&!now)) ans|=1<<(i-1); } return ans; } void Dp() { memset(dp,0,sizeof dp); memset(opt,0,sizeof opt); opt[1][0]=0; opt[1][1]=1; dp[1][0]=1; dp[1][1]=1; for(int i=2;i<=24;i++) { int ends=(1<<i)-1; for(int st=0;st<=ends;st++) { int s=nextState(st,i); int cnt; cnt=opt[i%2][st]=opt[(i-1)%2][s]+bitcount(st); dp[i][cnt]++; } } } int main() { FILE *f=fopen("G:\\ans.txt","w"); int n; Dp(); for(int n=1;n<=24;n++) { if(n==0)break; if(n*(n+1)%4) fprintf(f,"ans[%d]=0;\n",n); else fprintf(f,"ans[%d]=%d;\n",n,dp[n][n*(n+1)/4]); } return 0; }
#include<iostream> #include<math.h> #include<stdio.h> #include<algorithm> #include<string.h> #include<vector> #include<map> using namespace std; typedef long long ll; const int oo=0x3f3f3f3f; const ll OO=1LL<<61; const ll MOD=1000000007; const int maxn=25; int ans[maxn]; void GetAns() { ans[1]=0; ans[2]=0; ans[3]=4; ans[4]=6; ans[5]=0; ans[6]=0; ans[7]=12; ans[8]=40; ans[9]=0; ans[10]=0; ans[11]=171; ans[12]=410; ans[13]=0; ans[14]=0; ans[15]=1896; ans[16]=5160; ans[17]=0; ans[18]=0; ans[19]=32757; ans[20]=59984; ans[21]=0; ans[22]=0; ans[23]=431095; ans[24]=822229; } int main() { int n; GetAns(); while(scanf("%d",&n)!=EOF) { if(n==0)break; printf("%d %d\n",n,ans[n]); } return 0; }