标签:tran tab blank other print eof cin order amp
题目大意:有三种天气和四种湿度。给出在每种天气下四种湿度的概率,和天气之间的转移概率,如今给出一个n天的湿度序列,要求给出一个概率最大的天气序列。
思路:非常easy的概率DP。转移概率和状态概率都给好了。设dp[i][j]表示第i天是第j种天气的最大概率。然后pre[i][j]来记录序列顺序。
如果第i-1天是第j1种天气。第i天是j2种天气。天气转移概率为p1[j1][j2],第i天的湿度为x,在第j2种天气下x湿度的概率为p2[j2][x],则有:
dp[i][j2]=max(dp[i-1][j1]*p1[j1][j2]*p2[j2][x]),记录最大值是由哪一个j1转移过来的,用pre[i][j2]记录。最后求得最大的dp[n][j]。依据pre数组输出路径就可以。
注:题目中说因为dp[n][j]可能非常小。用double乘可能会掉精度,所以要用log,可是我直接乘也过了,可能是运气比較好吧,以后这样的问题还是要多注意。
#include <iostream> #include <string.h> #include <stdio.h> #include <algorithm> #include <math.h> #include <string> #include <map> #include <vector> #define maxn 55 using namespace std; double dp[55][3]; int pre[55][3]; map<string,int> mp; string str; double p1[3][4]={0.6,0.2,0.15,0.05,0.25,0.3,0.2,0.25,0.05,0.1,0.35,0.5}; double p2[3][3]={0.5,0.375,0.125,0.25,0.125,0.625,0.25,0.375,0.375}; void init() { mp.insert(make_pair("Dry",0)); mp.insert(make_pair("Dryish",1)); mp.insert(make_pair("Damp",2)); mp.insert(make_pair("Soggy",3)); } int main() { int ncase,T=0; scanf("%d",&ncase); init(); while(ncase--) { printf("Case #%d:\n",++T); int n; scanf("%d",&n); cin>>str; for(int i=0;i<=n;i++) { for(int j=0;j<3;j++) dp[i][j]=0; } int lab=mp[str]; memset(pre,0,sizeof(pre)); dp[1][0]=0.63*p1[0][lab]; dp[1][1]=0.17*p1[1][lab]; dp[1][2]=0.2*p1[2][lab]; for(int i=2;i<=n;i++) { cin>>str; int lab=mp[str]; for(int j=0;j<3;j++) { for(int k=0;k<3;k++) { double pp=dp[i-1][k]*p2[k][j]*p1[j][lab]; if(pp>dp[i][j]) { dp[i][j]=pp; pre[i][j]=k; } } } } vector<int> ans; double mi=0; int po; for(int i=0;i<3;i++) { if(dp[n][i]>mi) { mi=dp[n][i]; po=i; } } ans.push_back(po); int now=n; while(now!=1) { po=pre[now][po]; ans.push_back(po); now--; } for(int i=n-1;i>=0;i--) { if(ans[i]==0) printf("Sunny\n"); else if(ans[i]==1) printf("Cloudy\n"); else printf("Rainy\n"); } } return 0; }
hdu 4865 Peter's Hobby(2014 多校联合第一场 E)
标签:tran tab blank other print eof cin order amp
原文地址:http://www.cnblogs.com/brucemengbm/p/7098378.html