第一次做dp
题目
扔骰子,给出扔出每个点的概率,求出到达特定点的概率是多少。。这里所有特定点的和并不是100%,每个特定点的计算是将每一次(共十次)经过它的概率都加起来求和。得到100%的情况是将每次经过的每个点的概率求和(例如第一次经过一二三四五六这六个点的所有概率加起来是100)
这个二维dp
一是要将到的点记录一下,二是要将扔骰子的次数记录一下,都与上一次扔的有关系,是上一次的状态再乘一个概率。
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
double dp[66][11];
double ans[7];
double a[56];
int main()
{
int t;
scanf("%d", &t);
while (t--) {
int i;
memset(dp, 0, sizeof(dp));
memset(a, 0, sizeof(a));
for (i = 1; i <= 6; i++)
{
cin >> ans[i];
dp[i][1] = ans[i];
}
int j, k;
for (i = 2; i < 11; i++)
for (j = 0; j < 61; j++)
for (k = 1; k <= 6; k++)
if(j-k>0)
dp[j][i] += dp[j-k][i-1] * ans[k]; //一定是+=不是=,因为即使扔相同次,也有可能有多种经过这点的情况,因为上一次扔的点不相同,比如1+2=2+1
for (i = 1; i <= 10; i++)
a[5] += dp[5][i];
for (i = 1; i <= 10; i++)
a[12] += dp[12][i];
for (i = 1; i <= 10; i++)
a[22] += dp[22][i];
for (i = 1; i <= 10; i++)
a[29] += dp[29][i];
for (i = 1; i <= 10; i++)
a[33] += dp[33][i];
for (i = 1; i <= 10; i++)
a[42] += dp[42][i];
for (i = 1; i <= 10; i++)
a[46] += dp[46][i];
for (i = 1; i <= 10; i++)
a[50] += dp[50][i];
for (i = 1; i <= 10; i++)
a[55] += dp[55][i];
for (i = 1; i <= 10; i++)
a[38] += dp[38][i];
printf("5: %.1f%%\n", a[5]*100);
printf("12: %.1f%%\n", a[12] * 100);
printf("22: %.1f%%\n", a[22] * 100);
printf("29: %.1f%%\n", a[29] * 100);
printf("33: %.1f%%\n", a[33] * 100);
printf("38: %.1f%%\n", a[38] * 100);
printf("42: %.1f%%\n", a[42] * 100);
printf("46: %.1f%%\n", a[46] * 100);
printf("50: %.1f%%\n", a[50] * 100);
printf("55: %.1f%%\n", a[55] * 100);
if (t)
printf("\n");
}
}