題目大意:已知N天的天氣溼度 求出N天最可能的天氣狀況。其中當天的天氣狀況
與前一天的天氣相關,當天的空氣溼度與當前的天氣狀況相關。第一天
不同天氣狀況概率已經給出。
思路: 求出不同天氣下該種天氣溼度的概率 通過找到最大的概率可推知當前的天氣
狀況 由於當前天氣受前一天的影響 因此打表求出每一天不同天氣狀況之
下對於空氣溼度k的概率 之後可利用數組回溯找到對應天氣狀況
假設dp[i][j] 爲當前天氣狀況爲i 時空氣溼度爲j時的概率 則
dp[i][j] = dp[i-1][k]*waether[k][m]*wep[m][j]
表示i-1天第k種天氣狀況的概率* 第i天m天氣狀況的轉換概率*m天氣下的空氣溼度
由於後一天受前一天的影響,所以每天的天氣狀況並不是對對應溼度概率最大的天氣
而是根據最後一天概率最大的天氣往前推的最可能的天氣
類似的精度問題應該使用log()
代碼如下:
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
double dp[4][5]={{0,0},{0,0.5,0.375,0.125},{0,0.25,0.125,0.625},{0,0.25,0.375,0.375}};
double wep[4][5]={{0,0},{0,0.6,0.2,0.15,0.05},{0,0.25,0.3,0.2,0.25},{0,0.05,0.10,0.35,0.50}};
int num[55];
int pre[55][5],ans[55];
void solve(int n)
{
double f[55][5]={-0.10000000};
f[1][1]=0.63*wep[1][num[1]];
f[1][2]=0.17*wep[2][num[1]];
f[1][3]=0.20*wep[3][num[1]];
for(int i=2;i<=n;i++){
for(int j=1;j<=3;j++){
double ma=-0.10000;
int ti=0;
for(int k=1;k<=3;k++){
double temp=f[i-1][k]*dp[k][j]*wep[j][num[i]];
if(ma<temp)
{ma=temp;ti=k;}
}
f[i][j]=ma,pre[i][j]=ti;
}
}
double ma=-0.10000;
int ti=-1;
for(int j=1;j<=3;j++)
if(f[n][j]>ma){
ma=f[n][j];
ti=j;
}
ans[n]=ti;
for(int j=n;j>=2;j--){
ans[j-1]=pre[j][ti];
ti=pre[j][ti];
}
return ;
}
int main()
{
int t,n,i,j,w;
char wet[10];
scanf("%d",&t);
for(i=1;i<=t;i++){
scanf("%d",&n);
getchar();
for(j=1;j<=n;j++){
gets(wet);
if(!strcmp(wet,"Dry"))
num[j]=1;
else if(!strcmp(wet,"Dryish"))
num[j]=2;
else if(!strcmp(wet,"Damp"))
num[j]=3;
else
num[j]=4;
}
solve(n);
printf("Case #%d:\n",i);
for(j=1;j<=n;j++){
if(ans[j]==1)
printf("Sunny\n");
else if(ans[j]==2)
printf("Cloudy\n");
else
printf("Rainy\n");
}
}
return 0;
}