Description
Input
Output
Sample Input
2 1 2
1 2 1
0.8 0.2 0.5
1 2 5
1 3 3
2 3 1
Sample Output
感觉这场NOIP第一天的第三题和第二题难度放反了啊。。
这题不是直接一路推过去就好了。。
考虑f[i][j][k]表示前i个数,已经交换了j次,当前是否交换
那么转移方程为:
f[i][j][0]=f[i-1][j][0]+mp[c[i-1][1]][c[i][1]];
f[i][j][0]=min(f[i][j][0],f[i-1][j][1]+p[i-1]*mp[c[i-1][2]][c[i][1]]+(1.0-p[i-1])*mp[c[i-1][1]][c[i][1]]);
f[i][j][1]=f[i-1][j-1][0]+p[i]*mp[c[i-1][1]][c[i][2]]+(1.0-p[i])*mp[c[i-1][1]][c[i][1]];
f[i][j][1]=min(f[i][j][1],f[i-1][j-1][1]+p[i-1]*p[i]*mp[c[i-1][2]][c[i][2]]+(1.0-p[i-1])*p[i]*mp[c[i-1][1]][c[i][2]]+p[i-1]*(1.0-p[i])*mp[c[i-1][2]][c[i][1]]+(1.0-p[i-1])*(1.0-p[i])*mp[c[i-1][1]][c[i][1]]);
就是考虑前后交不交换的贡献就可以了
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
double f[2001][2001][2];
int c[2001][3];
double p[2001];
double mp[301][301];
int main()
{
int n,m,v,e;
scanf("%d%d%d%d",&n,&m,&v,&e);
int i,j,k;
for(i=1;i<=n;i++)
scanf("%d",&c[i][1]);
for(i=1;i<=n;i++)
scanf("%d",&c[i][2]);
for(i=1;i<=n;i++)
scanf("%lf",&p[i]);
int s,t;
double x;
//memset(mp,127/3,sizeof(mp));
for(i=1;i<=v;i++)
for(j=1;j<=v;j++)
mp[i][j]=2100000000;
for(i=1;i<=e;i++)
{
scanf("%d%d%lf",&s,&t,&x);
mp[s][t]=min(mp[s][t],x);
mp[t][s]=min(mp[t][s],x);
}
for(i=1;i<=v;i++)
mp[i][i]=0;
for(k=1;k<=v;k++)
for(i=1;i<=v;i++)
for(j=1;j<=v;j++)
if(mp[i][k]+mp[k][j]<mp[i][j])
mp[i][j]=mp[i][k]+mp[k][j];
for(i=0;i<=n;i++)
for(j=0;j<=m;j++)
f[i][j][0]=f[i][j][1]=2100000000;
f[1][0][0]=0;
f[1][1][1]=0;
for(i=2;i<=n;i++)
{
for(j=0;j<=m;j++)
{
f[i][j][0]=f[i-1][j][0]+mp[c[i-1][1]][c[i][1]];
f[i][j][0]=min(f[i][j][0],f[i-1][j][1]+p[i-1]*mp[c[i-1][2]][c[i][1]]+(1.0-p[i-1])*mp[c[i-1][1]][c[i][1]]);
if(j!=0)
{
f[i][j][1]=f[i-1][j-1][0]+p[i]*mp[c[i-1][1]][c[i][2]]+(1.0-p[i])*mp[c[i-1][1]][c[i][1]];
f[i][j][1]=min(f[i][j][1],f[i-1][j-1][1]+p[i-1]*p[i]*mp[c[i-1][2]][c[i][2]]+(1.0-p[i-1])*p[i]*mp[c[i-1][1]][c[i][2]]+p[i-1]*(1.0-p[i])*mp[c[i-1][2]][c[i][1]]+(1.0-p[i-1])*(1.0-p[i])*mp[c[i-1][1]][c[i][1]]);
}
}
}
double ans=2100000000;
for(j=0;j<=m;j++)
{
ans=min(ans,f[n][j][0]);
ans=min(ans,f[n][j][1]);
}
printf("%.2f\n",ans);
return 0;
}