zoukankan      html  css  js  c++  java
  • luogu1850 [NOIp2016]换教室 (floyd+dp)

    首先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 }
  • 相关阅读:
    Oracle+PL+SQL从入门到精通.丁士锋.清华大学出版社.2012
    《 Oracle查询优化改写 技巧与案例 》电子工业出版社
    HTML5从入门到精通(明日科技) 中文pdf扫描版
    《JavaWeb从入门到精通》(明日科技,清华大学出版社)
    JavaScript从入门到精通(附光盘1张):作者:明日科技出版社:清华大学出版社出版时间:2012年09月
    ORACLE_修改实例的内存大小
    JAVA图书管理系统汇总共27个
    IntelliJ Idea 2017 免费激活方法
    spring springMvc spring-boot spring-cloud分别是什么
    nodejs环境 + 入门 + 博客搭建
  • 原文地址:https://www.cnblogs.com/Ressed/p/9696075.html
Copyright © 2011-2022 走看看