将一个骰子投掷n次,获得的总点数为s,s的可能范围为n~6n。
掷出某一点数,可能有多种掷法,例如投掷2次,掷出3点,共有[1,2],[2,1]两种掷法。
请求出投掷n次,掷出n~6n点分别有多少种掷法。
样例1
输入:n=1
输出:[1, 1, 1, 1, 1, 1]
解释:投掷1次,可能出现的点数为1-6,共计6种。每种点数都只有1种掷法。所以输出[1, 1, 1, 1, 1, 1]。
样例2
输入:n=2
输出:[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]
解释:投掷2次,可能出现的点数为2-12,共计11种。每种点数可能掷法数目分别为1,2,3,4,5,6,5,4,3,2,1。
所以输出[1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]。
解题思路1:
#include <iostream>
using namespace std;
int n;
const int N=10010;
int f[N][N];//总的解法
int main(){
cin>>n;
for(int i=1;i<=n;i++)//次数
for(int j=i;j<=6*i;j++){
//点数
for(int k=1;k<=6;k++){
//骰子值得变化
//f[1][k]=1;
if(j>k)
f[i][j]+=f[i-1][j-k];//状态转移
else {
if(i==1)
f[1][k]=1;//初始化值
}
}
}
int i=n;
while(i<=6*n){
cout<<f[n][i]<<" ";
i++;
}
return 0;
}
解题思路2:
#include <iostream>
using namespace std;
int n;
const int N=10010;
int f[N];//总的解法 二维数组看起来比较清楚
int main(){
cin>>n;
for(int i=1;i<=n;i++)//次数
for(int j=6*i;j>=1;j--){
//点数
f[j]=0;//每次使用前都要清空一下里面的值 必须j>=1 否则就会出错
for(int k=6;k>=1;k--){
//骰子值得变化
if(j>k){
f[j]+=f[j-k];//状态转移
}
else {
if(i==1)
f[k]=1;//初始化值
}
}
}
int i=n;
while(i<=6*n){
cout<<f[i]<<" ";
i++;
}
return 0;
}