试题 算法训练 印章-蓝桥杯
/* DP: Dynamic programming, 动态规划 。 建议大家先在网上搜一搜动态规划 ,加深一下理解。 核心:拆分子,记住过往,减少重复计算,并用于计算结果。神似递归。 2022/1/27 fevergo 明鹊 。。。 希望对你有帮助 。 */ #include<iostream> #include<cmath> using namespace std; int main() { int n, m; cin>>n>>m; double pn = 1.0/n; double p[21][21]; for(int i = 1;i<=n;i++) for(int j = 1;j<=m;j++) { if(i>j) {p[i][j] = 0;} if(i == 1) {p[i][j] = pow(pn, j-1);} else{p[i][j] = p[i][j-1]*(i*pn)+p[i-1][j-1]*((n-(i-1))*pn);} } printf("%.4lf", p[n][m]); return 0; }
/* DP: Dynamic programming, 动态规划 。 建议大家先在网上搜一搜动态规划 ,加深一下理解。 核心:拆分子,记住过往,减少重复计算,并用于计算结果。神似递归。 2022/1/27 fevergo 明鹊 。。。 希望对你有帮助 。 */ #include<iostream> #include<cmath> using namespace std; int main() { int n, m; cin>>n>>m; // 有 n种印章, 买了 m个 double pn = 1.0/n; // 从印章里取一个的概率。 double p[21][21]; // 初始化数组,记住过往。 // p[i][j] 代表 现有 i 种,买 j个集齐的概率 (拆分子) for(int i = 1;i<=n;i++) for(int j = 1;j<=m;j++) { if(i>j) {p[i][j] = 0;} // 例如 现有 i种,买了j个,i>j, 肯定集不齐。 if(i == 1) {p[i][j] = pow(pn, j-1);} // 现有 1种,买了m个集齐 = 买了m个全是1种。 else{p[i][j] = p[i][j-1]*(i*pn)+p[i-1][j-1]*((n-(i-1))*pn);} // 现有 i 种,买了 j 个集齐 : // 记住过往,减少重复计算,并用于计算结果, //1.重复的情况: p[i][j-1] * (i*pn) ,(i*pn)是最后一张重复的概率 //2.不重复的情况: p[i-1][j-1]*((n-(i-1))*pn), (n-(i-1))*pn是最后一张不重复的概率 } printf("%.4lf", p[n][m]); // 格式输出 return 0; }
上一篇:
92天倒计时,蓝桥杯省赛备赛攻略来啦~