(三)
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; }