• Codeforces704B. Ant Man


    n<=5000个数轴上的点,有属性x,a,b,c,d,从i跳到j的代价如下:

    问从s跳到t的最小代价。

    方法?:先构造s->t链,然后依次插入其他点,每次选个最佳的位置。过了这题,正确性不明。

    方法:从边的向左向右入手。从左到右计算时,有些点想射出一条边却还射不出,有些点想被一条边插上却没边插他,好吧那这些待插(边方向向左)待射(边方向向右)的边决定了状态。同时可以愉快地发现平时出边(右)和入边(左)是一样多的,遇到s时入边(向左)少一条,遇到t时出边(向右)少一条,这可开个变量记。

    那$f(i,j)$--前i个点,j条边向右的最小代价,转移比较复杂:

    如果i+1是点s,f(i,j)可以转移到f(i+1,j+1)和f(i,j);

    如果i+1是点t,f(i,j)可以转移到f(i+1,j-1)和f(i,j);

    否则,f(i,j)可以转移到f(i+1,j),f(i+1,j-1),f(i+1,j+1)。

    当然这跟当前剩下的射出边(向右)和待入边(向左)是否足够(>0)有关。因此要判断转移的合法。

    小细节:未到终态,且不在s和t之间时,向右边0的状态不合法!!

     1 #include<string.h>
     2 #include<stdlib.h>
     3 #include<stdio.h>
     4 #include<math.h>
     5 //#include<assert.h>
     6 #include<algorithm>
     7 //#include<iostream>
     8 using namespace std;
     9 
    10 int n,s,t;
    11 #define maxn 5011
    12 #define LL long long
    13 int a[maxn],b[maxn],c[maxn],d[maxn],xx[maxn];
    14 LL f[maxn][maxn];
    15 int main()
    16 {
    17     scanf("%d%d%d",&n,&s,&t);
    18     for (int i=1;i<=n;i++) scanf("%d",&xx[i]);
    19     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    20     for (int i=1;i<=n;i++) scanf("%d",&b[i]);
    21     for (int i=1;i<=n;i++) scanf("%d",&c[i]);
    22     for (int i=1;i<=n;i++) scanf("%d",&d[i]);
    23     
    24     for (int i=0;i<=n;i++)
    25         for (int j=0;j<=n;j++)
    26             f[i][j]=1e18;
    27     f[0][0]=0;
    28     int havest=0;
    29     for (int i=0;i<n;i++)
    30     {
    31         if (i==s) havest--;
    32         if (i==t) havest++;
    33         (i && (havest==0) && (f[i][0]=1e18));
    34         for (int j=0;j<=n;j++) if (f[i][j]!=1e18)
    35         {
    36             if (i+1==s)
    37             {
    38                 if (j+havest) f[i+1][j]=min(f[i+1][j],f[i][j]+xx[i+1]+c[i+1]);
    39                 f[i+1][j+1]=min(f[i+1][j+1],f[i][j]-xx[i+1]+d[i+1]);
    40             }
    41             else if (i+1==t)
    42             {
    43                 if (j) f[i+1][j-1]=min(f[i+1][j-1],f[i][j]+xx[i+1]+a[i+1]);
    44                 f[i+1][j]=min(f[i+1][j],f[i][j]-xx[i+1]+b[i+1]);
    45             }
    46             else
    47             {
    48                 if (j) f[i+1][j]=min(f[i+1][j],f[i][j]+a[i+1]+d[i+1]);
    49                 if (j+havest) f[i+1][j]=min(f[i+1][j],f[i][j]+b[i+1]+c[i+1]);
    50                 if (j && j+havest) f[i+1][j-1]=min(f[i+1][j-1],f[i][j]+2*xx[i+1]+a[i+1]+c[i+1]);
    51                 f[i+1][j+1]=min(f[i+1][j+1],f[i][j]-2*xx[i+1]+b[i+1]+d[i+1]);
    52             }
    53         }
    54     }
    55     printf("%lld
    ",f[n][0]);
    56     return 0;
    57 }
    View Code
  • 相关阅读:
    test
    有偏估计和无偏估计
    Spark Shuffle
    Adaboost算法推导
    Spark优化 – 基础篇
    决策树 – 回归
    HBase的文件合并(minor/major compact)
    HBase的列式存储
    centos7配置固定ip
    Generate a Certificate Signing Request (CSR) in macOS Keychain Access
  • 原文地址:https://www.cnblogs.com/Blue233333/p/8277811.html
Copyright © 2020-2023  润新知