leetcode算法题--掷骰子模拟★★

原题链接:https://leetcode-cn.com/problems/dice-roll-simulation/

动态规划:

dp[i][j][k]表示投掷第i次,点数为j,k表示连续次数

状态转移:

  • 当j非连续出现时(即k==1时):
//j出现一次的组合数等于上一轮投出非点数j的所有情况和
dp[i][j][1]=sum(dp[i-1][!j][:])      
  • 当j连续出现时(即k>1时):
//本轮投出连续k次的点数j的数量情况等于上一轮连续投出k-1次的点数j的数量情况
dp[i][j][k]=dp[i-1][j][k-1]		if k<=rolMax[j]

代码:

int dieSimulator(int n, vector<int>& rollMax) {
     
	int mod = 1000000007;
	vector<vector<vector<int>>> dp(n + 1, vector<vector<int>>(7, vector<int>(16, 0)));
	for (int i = 1; i <= n; i++){
     //投掷次数
		for (int j = 1; j <= 6; j++){
     
			if (i == 1){
     //第一次投掷
				dp[i][j][1] = 1;
				continue;
			}
			for (int k = 2; k <= rollMax[j - 1]; k++){
     //数字j连续出现k次
				dp[i][j][k] = dp[i - 1][j][k - 1];//本轮投出连续k次数字j的情况数量等于:上一轮连续投出k-1次j的情况数量
			}
			int s = 0;
			for (int t = 1; t <= 6; t++){
     //前一次投出的数不是j
				if (t == j) continue;
				for (int k = 1; k <= 15; k++){
     
					s += dp[i - 1][t][k];//j出现一次的组合数等于上一轮所有投出非数字j的所有情况和
					s %= mod;
				}
			}
			dp[i][j][1] = s;
		}
	}
	int ans = 0;
	for (int j = 1; j <= 6; j++){
     //投掷n次时所有组合总和
		for (int k = 1; k <= 15; k++){
     
			ans += dp[n][j][k];
			ans %= mod;
		}
	}
	return ans;
}

你可能感兴趣的:(算法)