好久以前做的了
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
const int N1=2010;
const int N2=310;
double dp[N1][N1][2];
//dp[i][j][0]表示前i个时间段用j次申请(第i个不申请)所需要的最小体力值
//dp[i][j][1]表示申请
double k[N1];//通过概率
int c[N1];//安排教室
int d[N1];//另外教室
int dis[N1][N1];//边权
int main()
{
//freopen("in.txt","r",stdin);
int n,m,v,e,a,b;
scanf("%d%d%d%d",&n,&m,&v,&e);//时间,申请,教室,道路
int i,j,l,w;//边权
for(i=1;i<=n;i++)
scanf("%d",&c[i]);//安排
for(i=1;i<=n;i++)
scanf("%d",&d[i]);//另外
for(i=1;i<=n;i++)
scanf("%lf",&k[i]);//概率
memset(dis,127/2,sizeof(dis));
for(i=1;i<=e;i++)
{
scanf("%d%d%d",&a,&b,&w);
dis[a][b]=min(dis[a][b],w);
dis[b][a]=min(dis[b][a],w);
}
for(i=1;i<=v;i++)dis[i][i]=0;
for(l=1;l<=v;l++)
for(i=1;i<=v;i++)
for(j=1;j<=v;j++)
if(dis[i][j]>dis[i][l]+dis[l][j])//处理最短路
dis[i][j]=dis[i][l]+dis[l][j];
for(i=1;i<=v;i++)dis[0][i]=0;
for(i=0;i<=2009;i++)
for(j=0;j<=2009;j++)
for(l=0;l<=1;l++)
dp[i][j][l]=INF;
//memset(dp,0x3f,sizeof(dp));
dp[0][0][0]=0;
for(i=0;i<=n-1;i++)
for(j=0;j<=m;j++)
{
dp[i+1][j][0]=min(dp[i][j][0]+dis[c[i]][c[i+1]],dp[i][j][1]+dis[d[i]][c[i+1]]*k[i]+dis[c[i]][c[i+1]]*(1.0-k[i]));
if(j!=m)dp[i+1][j+1][1]=min(dp[i][j][0]+dis[c[i]][d[i+1]]*k[i+1]+dis[c[i]][c[i+1]]*(1.0-k[i+1]),dp[i][j][1]+dis[c[i]][c[i+1]]*(1.0-k[i+1])*(1.0-k[i])+dis[d[i]][c[i+1]]*(1.0-k[i+1])*k[i]+dis[c[i]][d[i+1]]*k[i+1]*(1.0-k[i])+dis[d[i]][d[i+1]]*k[i]*k[i+1]);
}
double ans=INF;
for(j=0;j<=m;j++)
{
ans=min(ans,min(dp[n][j][0],dp[n][j][1]));
}
printf("%.2lf\n",ans);
return 0;
}
总结
无