您的位置:首页 > 其它

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

2015-02-18 13:59 453 查看
题意:

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

例如:

+ + - + - + +

+ - - - - +

- + + + -

- + + -

- + -

- -

+

题解:

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+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
);
    }
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: