首先floyd求出每两点间的距离(注意自己到自己的距离要设成0)
然后就是dp了
一开始照着Lifeguards的样子,钦定了一下i这个点一定要选,然后发现复杂度不对,还想了好长时间优化
然后一翻题解,直接两种状态选或不选分开算O(1)转移多好(所以年轻人不要整天满脑子都是钦定钦定的)
但为什么Lifeguards要钦定呢?因为如果你有一个删掉的状态,那我无法确定前面的到底到哪是没删的
那就是$f[i][j][1/0]=max(f[i][j][1/0]+....)$,f[i][j][0/1]是换到第i个、换了j个、i号没换/换了的最小值
....的内容大概就是这几种状态间转移的期望,讨论讨论就行了
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define lowb(x) ((x)&(-(x))) 4 #define REP(i,n0,n) for(i=n0;i<=n;i++) 5 #define PER(i,n0,n) for(i=n;i>=n0;i--) 6 #define MAX(a,b) ((a>b)?a:b) 7 #define MIN(a,b) ((a<b)?a:b) 8 #define CLR(a,x) memset(a,x,sizeof(a)) 9 #define rei register int 10 using namespace std; 11 typedef long long ll; 12 const int maxn=2020,maxm=2020,maxv=310; 13 14 inline ll rd(){ 15 ll x=0;char c=getchar();int neg=1; 16 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 17 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 18 return x*neg; 19 } 20 21 int N,M,V,E; 22 int pos[maxn][2],dis[maxn][maxn]; 23 int sum[maxn]; 24 double f[maxn][maxn][2],c[maxn]; 25 26 void floyd(){ 27 for(int i=1;i<=V;i++) dis[i][i]=0; 28 for(int i=1;i<=V;i++){ 29 for(int j=1;j<=V;j++){ 30 for(int k=1;k<=V;k++){ 31 if(dis[j][i]>=1e9||dis[i][k]>=1e9) continue; 32 dis[j][k]=min(dis[j][i]+dis[i][k],dis[j][k]); 33 } 34 } 35 } 36 } 37 38 int main(){ 39 //freopen(".in","r",stdin); 40 int i,j,k; 41 N=rd(),M=rd(),V=rd(),E=rd(); 42 if(N==1){printf("0.00 ");return 0;} 43 for(i=1;i<=N;i++) pos[i][0]=rd(); 44 for(i=1;i<=N;i++) pos[i][1]=rd(); 45 for(i=1;i<=N;i++) scanf("%lf",&c[i]); 46 memset(dis,127,sizeof(dis)); 47 for(i=1;i<=E;i++){ 48 int a=rd(),b=rd(),c=rd(); 49 dis[a][b]=min(dis[a][b],c); 50 dis[b][a]=min(dis[b][a],c); 51 }floyd(); 52 for(i=1;i<=N;i++) for(j=0;j<=M;j++) f[i][j][0]=f[i][j][1]=1e9; 53 f[1][0][0]=f[1][1][0]=f[1][1][1]=0; 54 for(i=2;i<=N;i++){ 55 for(j=0;j<=min(i,M);j++){ 56 f[i][j][0]=min(f[i-1][j][0]+dis[pos[i-1][0]][pos[i][0]], 57 f[i-1][j][1]+dis[pos[i-1][0]][pos[i][0]]*(1-c[i-1])+dis[pos[i-1][1]][pos[i][0]]*c[i-1]); 58 if(j){ 59 f[i][j][1]=min(f[i-1][j-1][0]+dis[pos[i-1][0]][pos[i][0]]*(1-c[i])+dis[pos[i-1][0]][pos[i][1]]*c[i], 60 f[i-1][j-1][1]+(dis[pos[i-1][0]][pos[i][0]]*(1-c[i])+dis[pos[i-1][0]][pos[i][1]]*c[i])*(1-c[i-1])+ 61 (dis[pos[i-1][1]][pos[i][0]]*(1-c[i])+dis[pos[i-1][1]][pos[i][1]]*c[i])*c[i-1]); 62 } 63 } 64 } 65 double ans=1e9; 66 for(i=0;i<=M;i++) ans=min(ans,min(f[N][i][0],f[N][i][1])); 67 printf("%.2lf ",ans); 68 return 0; 69 }