hdu 2510 符号三角形 (状压dp打表存入文件,O(1))

来源:互联网 发布:卡在client mac addr 编辑:程序博客网 时间:2024/05/16 12:13

题意:

给出一个只有正负号组成的金字塔,金字塔满足同号的正,异号得负。

例如:

+ + - + - + + 
  + - - - - + 
  - + + + - 
   - + + - 
    - + - 
     - - 
     +

题解:

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;}


0 0
原创粉丝点击