2020百度之星

(三)

Chess(经典DP)

http://acm.hdu.edu.cn/showproblem.php?pid=6787

思路:

考虑如果棋盘上连续放置了 11 个传送器,那么这个区域就是无法通过骰子跨过的。而对于一个区域而言,只要上面没有连续 11 个传送器,我们就可以通过控制骰子而成功达到每个可达到的点。由此可以得到一个 dp 方程:设 f[i][j][k] 表示当前考虑到第i个格子,已经用了j个传送器,包括i号位置有连续k个传送器。那么我们的决策就是第i号位置是否放传送器。

代码:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod= 1e9+7;
inline int read(){
    int k=0,j=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') j=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){k*=10;k+=ch-'0';ch=getchar();}
    return j*k;
}
int dp[1005][1005][11];
int main()
{
    int t;scanf("%d",&t);
    while(t--){
        int n=read(),m=read();
        memset(dp,0,sizeof(dp));
        dp[1][0][0] = 1;
        for(int i=2;i<=n;i++){
            for(int j=0;j<=m;j++){
                for(int k=0;k<=10;k++) dp[i][j][0]=(dp[i-1][j][k]+dp[i][j][0])%mod;
                if(i!=n&&j) for(int k=1;k<=10;k++)
                    dp[i][j][k]=(dp[i][j][k]+1ll*dp[i-1][j-1][k-1]*(i-1)%mod)%mod;
            }
        }
        printf("%d\n",dp[n][m][0]?dp[n][m][0]:-1);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/rainartist/p/13382555.html