动态规划求一定数量骰子和的概率
2018华为实习机试
题目描述:略
动态规划:
f(n,s)=f(n-1,s-1)+f(n-1,s-2)+f(n-1,s-3)+.....+f(n-1,s-6) 至于f(n-1,s-k)是否存在,由Record的getinfo()判断,不存在就设为0
1 #include <iostream> 2 #include<vector> 3 #include<iomanip> 4 #include<cmath> 5 6 using namespace std; 7 class Record{ 8 public: 9 vector<vector<int>> data; 10 Record(){} 11 Record(int s) 12 { 13 data.resize(s); 14 for(int i=0;i<s;++i){ 15 data[i].resize(5*i+6); 16 } 17 } 18 bool addinfo(int dicenum,int sum,int cnt) 19 { 20 if(sum>=dicenum && sum<=dicenum*6){ 21 data[dicenum-1][sum-dicenum]=cnt; 22 return true; 23 } 24 else{ 25 return false; 26 } 27 } 28 int getinfo(int dicenum,int sum) 29 { 30 if(sum>=dicenum && sum<=dicenum*6){ 31 return data[dicenum-1][sum-dicenum]; 32 } 33 else{ 34 return 0; 35 } 36 } 37 }; 38 39 40 int main() 41 { 42 int dicenum; 43 int total; 44 while(cin >> dicenum){ 45 int smin,smax; 46 Record rec(dicenum); 47 total = (int)(0.5+pow(6,dicenum)); 48 for(int i=1;i<=dicenum;++i){ 49 smin = i; 50 smax = i*6; 51 if(i==1){ 52 for(int j=smin;j<=smax;++j){ 53 rec.addinfo(1,j,1); 54 } 55 } 56 else{ 57 for(int j=smin;j<=smax;++j){ 58 int tempcnt = 0; 59 for(int k=1;k<=6;++k){ 60 tempcnt += rec.getinfo(i-1,j-k); 61 } 62 rec.addinfo(i,j,tempcnt); 63 } 64 } 65 } 66 /*test rec data 67 for(int i=1;i<=dicenum;++i){ 68 int temp = 0; 69 cout << i << endl; 70 for(int j=i;j<=i*6;++j){ 71 if((temp=rec.getinfo(i,j))!=0){ 72 cout << temp << " "; 73 } 74 } 75 cout << endl; 76 } 77 */ 78 79 /* 80 output 1: 当数字很大时,结果不对称 81 double prob = 0; 82 cout << "["; 83 for(int i=smin;i<=smax;++i){ 84 prob = (double)(rec.getinfo(dicenum,i)) / total; 85 cout << "[" << i << ", "; 86 cout.flags(ios::fixed); 87 cout.precision(5); 88 cout << prob << "]"; 89 if(i != smax){ 90 cout << ", "; 91 } 92 } 93 cout << "]" << endl; 94 */ 95 96 //output 2:使输出结果对称,且减少运算量 97 vector<double> prob; 98 prob.resize((smax+smin)/2); 99 cout << "["; 100 for(int i=smin;i<=(smin+smax)/2;++i){ 101 prob[i-smin] = (double)(rec.getinfo(dicenum,i)) / total; 102 cout << "[" << i << ", "; 103 cout.flags(ios::fixed); 104 cout.precision(5); 105 cout << prob[i-smin] << "]" << ", "; 106 } 107 int tempsum = (smin+smax)/2+1; 108 for(int i=prob.size()-1;i>=0;--i){ 109 if(i==prob.size()-1){ 110 if((smin+smax)%2!=0){ 111 cout << "[" << tempsum << ", "; 112 cout.flags(ios::fixed); 113 cout.precision(5); 114 cout << prob[i] << "]" << ", "; 115 tempsum++; 116 } 117 } 118 else{ 119 cout << "[" << tempsum << ", "; 120 cout.flags(ios::fixed); 121 cout.precision(5); 122 cout << prob[i] << "]"; 123 tempsum++; 124 if(i!=0){ 125 cout << "], "; 126 } 127 } 128 } 129 cout << "]" << endl; 130 } 131 return 0; 132 }
程序缺陷:对于多个测例,没有将之前Record类的信息保留节省计算
posted on 2018-04-19 17:16 CreatorKou 阅读(209) 评论(0) 编辑 收藏 举报