题意:
给出一个只有正负号组成的金字塔,金字塔满足同号的正,异号得负。
例如:
+ + - + - + +
+ - - - - +
- + + + -
- + + -
- + -
- -
+
题解:
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;
}
ac程序
#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;
}