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 }
  • 相关阅读:
    Matlab 绘制三维立体图(以地质异常体为例)
    Azure DevOps的variable group实现array和hashtable参数的传递
    Azure DevOps 利用rest api设置variable group
    Azure AADSTS7000215 其中一种问题的解决
    Power BI 实现实时更新Streaming Dataset
    AAD Service Principal获取azure user list (Microsoft Graph API)
    Matlab 沿三维任意方向切割CT图的仿真计算
    Azure Powershell script检测登陆并部署ARM Template
    Azure KeyVault设置策略和自动化添加secrets键值对
    Azure登陆的两种常见方式(user 和 service principal登陆)
  • 原文地址:https://www.cnblogs.com/Ressed/p/9696075.html
Copyright © 2011-2022 走看看