[ZJOI2012]波浪弱化版(带技巧的DP)

题面

\(solution:\)

\(code:\)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>

#define ll long long
#define db double
#define inf 0x7fffffff
#define rg register int
#define mod 1000000007

using namespace std;

int n,m,s=1;
ll now,f[2][51][2501][3];

inline int qr(){
    char ch;
    while((ch=getchar())<'0'||ch>'9');
    int res=ch^48;
    while((ch=getchar())>='0'&&ch<='9')
        res=res*10+(ch^48);
    return res;
}

int main(){
    freopen("wave.in","r",stdin);
    freopen("wave.out","w",stdout);
    n=qr();m=qr();
    f[0][0][1198][2]=1;
    f[0][0][1199][1]=2;//初始化
    for(rg i=2;i<=n;++i,s^=1){
        memset(f[s],0,sizeof(f[s]));
        for(rg j=0;j<=49;++j)
            for(rg t=100;t<=2401;++t)
                for(rg k=0;k<=2;++k){




                    if(!(now=f[s^1][j][t][k]))continue;    //开始转移f[i][j][t][k]



                    f[i][j+1][t-i*2][k]+=f[i][j][t][k]*(j+k); //建一个新的块




                    
                    f[i][j][t][k]+=f[i][j][t][k]*(j*2+k);     //贴在一块旁边




                    
                    f[i][j-1][t+i*2][k]+=f[i][j][t][k]*j;//夹在两块中间




                    
                    f[i][j][t+i][k-1]+=now*k;     //放在端点且与一块相连




                    
                    f[i][j+1][t-i][k-1]+=now*k;   //放在端点且不与任何一个块相邻






                    
                }
    }printf("%lld\n",f[s^1][0][m+1200][0]%mod);
    return 0;

猜你喜欢

转载自www.cnblogs.com/812-xiao-wen/p/10331514.html
今日推荐