サイコロをn回投げると、得られるポイントの総数はsであり、sの可能な範囲はn〜6nです。
特定の数のポイントを投げるには、複数の投げ方があります。たとえば、2回投げる、3ポイントを投げる、2つの投げ方があります[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;
}