hdu6787(骰子+往回推的传输带问通过方案,dp)

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

题意:有1~n标号的格子,上面有m个传输带(传送带传的位置要传到之前去,1位置不能有格子)1~11的骰子,问有多少种安传输带的方案使得仍有可能从1到n(到n不动),期间位置不能超过n

分析:可以发现,只要不要连续安传输带的个数不大于10,则有可能从1到n,决策就是要不要在当前位置安传输带;

   设dp[i][j][k],表示在位置 i 用了 j 个传输带 从i开始连续有k个传输带的方案数,那么dp[i][j][k]就是由dp[i-1][j-1][k-1]*(i-1)得来的,其中*(i-1)代表在位置 i 装传输带可以传到的范围为[1,n-1] ,n-1种可能;

   k最多为10,在dp过程种累加即可

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int M=1e3+3;
const int mod=1e9+7;
int dp[M][M][13];
void init(){
    dp[2][0][0]=1;
    for(int i=2;i<=1000;i++)
        for(int j=0;j<=1000;j++)
            for(int k=0;k<=10;k++){
                dp[i+1][j+1][k+1]=(dp[i+1][j+1][k+1]+1ll*(i-1)*dp[i][j][k])%mod;
                dp[i+1][j][0]=(dp[i+1][j][0]+dp[i][j][k])%mod;
            }
}
int main(){
    init();
    int T;
    scanf("%d",&T);
    while(T--){
        int n,m;
        scanf("%d%d",&n,&m);
        if(m>max(0,n-2)){puts("-1");}
        else if(n<3){
            puts("1");
        }
        else
            printf("%d\n",dp[n+1][m][0]==0?-1:dp[n+1][m][0]);
    }
    return 0;
}
View Code

 

posted @ 2020-07-27 09:29  starve_to_death  阅读(263)  评论(4编辑  收藏  举报