HDU - 1438(圧力DPまたは再発など)

タイトル:クリック
溝の深さが3つ以上のi番目のスロットの前方を有することが図15に示す状態に0バイナリとすることができる必要があるため1、満たしは差が隣り合うの数に等しいか否かを状態決意を必要と3、直接DPすることができます。
2.再発。状態は以下の分析よりもために解析の問題は、一枚ずつ出てくることがあります。
違いは、わずか1状態3と適合するように隣接する4です。
私は2例に入社した後、i番目のスタートから、私の添加が成功の鍵となった後、成功への鍵になっていません。
11:I-1の最初のキーを設定されている場合、i番目の1234であってもよい;
22:最初のキーを変更するi番目の鍵を添加した後、構成しない場合は、I-1
。22A:あり私の前に相Oおよび差(POW(2、I-3であり、 1)-2)* 2( 除外されるフル必要が1又は4である)
22B:差異は、隣接する3つの私の前ではなく、( POW(4、N-2) -2-POW(2、N-2)+2)* 2;
従ってキーの後に配置が良好で、私はちょうど2、I-前に、1次に、I-1〜4でありますPUT、(その三種類に達した)すべての-1または全て4を除外する。しかし、ケースが満たされているを示している[I-1]の状況が満たされたときに、I-2、iは1オン引き起こし、一時を減算する必要がある、私は1を入れたときに、I-1は4ですが、1かもしれ言うとへ1又は4終わり。

両方のタグを添付:
1:

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
ll dp[35][20][5][2];// 第i个槽   前i个槽的状态j  第i个槽的值k  hh表示是否差值大于三
ll num[50];
int main()
{
    memset(dp,0,sizeof(dp));
    ll i,j,k;
    dp[1][1][0][0]=dp[1][2][1][0]=dp[1][4][2][0]=dp[1][8][3][0]=1;
    for(i=2;i<=31;i++)
    {
        for(j=0;j<16;j++)
        {
            for(k=0;k<4;k++)
            {
                for(ll hh=0;hh<4;hh++)
                    {
                        if(abs(k-hh)==3)
                        {
                            dp[i][(j|(1<<k))][k][1]+=dp[i-1][j][hh][1]+dp[i-1][j][hh][0];
                        }
                        else
                        {
                            dp[i][(j|(1<<k))][k][0]+=dp[i-1][j][hh][0];
                            dp[i][(j|(1<<k))][k][1]+=dp[i-1][j][hh][1];
                        }
                    }
            }
        }
    }
    for(i=2;i<=31;i++)
    {
        ll sum=0;
        for(j=0;j<16;j++)
        {
            ll cnt=0;
            for(ll hh=0;hh<4;hh++)
            {
                if((1<<hh)&j)
                    cnt++;
            }
            if(cnt<3)
                continue;
            for(k=0;k<4;k++)
            {
                sum+=dp[i][j][k][1];
            }
        }
        printf("N=%lld: %lld\n",i,sum);
    }
    return 0;
}

2:

#include<cmath>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<istream>
#include<vector>
#include<stack>
#include<set>
#include<map>
#include<algorithm>
#include<queue>
#define MAX_len 50100*4
using namespace std;
typedef long long ll;
ll ans[35];
ll temp[35];//以1 or 4结尾时钥匙
int main()
{
    ll i,j,k;
    ans[1]=0;
    ans[2]=0;
    ans[3]=8;
    temp[2]=0;
    temp[3]=4;
    printf("N=2: 0\n");
    printf("N=3: 8\n");
    for(i=4;i<=31;i++)
    {
        ans[i]=ans[i-1]*4+2*((ll)pow(2,i-1)-2)+(ll)(pow(4,i-2)-(ll)pow(2,i-2))*2-temp[i-1];
        temp[i]=ans[i-1]*2+((ll)pow(4,i-2)-(ll)pow(2,i-2))*2-temp[i-1];
        printf("N=%lld: %lld\n",i,ans[i]);
    }
    return 0;
}
公開された72元の記事 ウォン称賛19 ビュー7498

おすすめ

転載: blog.csdn.net/weixin_43958964/article/details/104786373