zoukankan      html  css  js  c++  java
  • BZOJ1742: [Usaco2005 nov]Grazing on the Run 边跑边吃草

    数轴上n<=1000个点,从p出发以任意顺序走到所有的点,求到达每个点的时间之和的最小值。

    好题!看起来水水的实际易错!

    显然的结论是经过一个区间点之后肯定落在左端点或右端点上,谁没事最后还往中间跑呢!那就可以拍个序然后设计dp状态了,一个区间dp,f[i,j,0/1]表示走了区间i~j,最后落在左/右端点。

    一个小技巧是把p算成一个点,初始化时之后p这个状态为0,其他都inf。那么问题来了!

    方法一:记到状态的时间t[i,j,0/1],那么,相应更新t,其他同理。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7  
     8 int n,p;
     9 #define maxn 1011
    10 int a[maxn],f[maxn][maxn][2],t[maxn][maxn][2];
    11 const int inf=0x3f3f3f3f;
    12 int min(int a,int b) {return a<b?a:b;}
    13 int main()
    14 {
    15     scanf("%d%d",&n,&p);
    16     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    17     sort(a+1,a+1+n);
    18     for (int i=1;i<=n;i++) f[i][i][0]=f[i][i][1]=t[i][i][0]=t[i][i][1]=inf;
    19     a[n+1]=inf;int pos;
    20     for (pos=1;pos<=n+1;pos++) if (a[pos]>p) break;
    21     if (pos==n+1) t[n][n][0]=t[n][n][1]=f[n][n][0]=f[n][n][1]=p-a[n];
    22     else if (pos==1) t[1][1][0]=t[1][1][1]=f[1][1][0]=f[1][1][1]=a[1]-p;
    23     else f[pos][pos][0]=f[pos][pos][1]=a[pos]-p,f[pos-1][pos-1][0]=f[pos-1][pos-1][1]=p-a[pos-1],
    24          t[pos][pos][0]=t[pos][pos][1]=a[pos]-p,t[pos-1][pos-1][0]=t[pos-1][pos-1][1]=p-a[pos-1];
    25     for (int len=1;len<n;len++)
    26         for (int i=1;i<=n-len;i++)
    27         {
    28             const int j=i+len;
    29             if (f[i+1][j][0]+t[i+1][j][0]+a[i+1]-a[i]<f[i+1][j][1]+t[i+1][j][1]+a[j]-a[i])
    30             {
    31                 t[i][j][0]=t[i+1][j][0]+a[i+1]-a[i];
    32                 f[i][j][0]=f[i+1][j][0]+t[i][j][0];
    33             }
    34             else
    35             {
    36                 t[i][j][0]=t[i+1][j][1]+a[j]-a[i];
    37                 f[i][j][0]=f[i+1][j][1]+t[i][j][0];
    38             }
    39             if (f[i][j-1][0]+t[i][j-1][0]+a[j]-a[i]<f[i][j-1][1]+t[i][j-1][1]+a[j]-a[j-1])
    40             {
    41                 t[i][j][1]=t[i][j-1][0]+a[j]-a[i];
    42                 f[i][j][1]=f[i][j-1][0]+t[i][j][1];
    43             }
    44             else
    45             {
    46                 t[i][j][1]=t[i][j-1][1]+a[j]-a[j-1];
    47                 f[i][j][1]=f[i][j-1][1]+t[i][j][1];
    48             }
    49             f[i][j][0]=min(f[i][j][0],inf);
    50             f[i][j][1]=min(f[i][j][1],inf);
    51         }
    52     printf("%d
    ",min(f[1][n][0],f[1][n][1]));
    53     return 0;
    54 }
    View Code

    错误!递推式不成立,没有考虑当前决策对后续状态的影响。错误样例?自己找个标程对拍吧!

    方法二:直接把状态对后面的影响算出来,,保证了无后效性。

     1 #include<stdio.h>
     2 #include<string.h>
     3 #include<stdlib.h>
     4 #include<algorithm>
     5 //#include<iostream>
     6 using namespace std;
     7 
     8 int n,p;
     9 #define maxn 1011
    10 int a[maxn],f[maxn][maxn][2];
    11 const int inf=0x3f3f3f3f;
    12 int min(int a,int b) {return a<b?a:b;}
    13 int main()
    14 {
    15     scanf("%d%d",&n,&p);
    16     for (int i=1;i<=n;i++) scanf("%d",&a[i]);
    17     a[++n]=p;
    18     sort(a+1,a+1+n);
    19     for (int i=1;i<=n;i++)
    20     {
    21         if (a[i]!=p) f[i][i][0]=f[i][i][1]=inf;
    22         else f[i][i][0]=f[i][i][1]=0;
    23     }
    24     for (int len=1;len<n;len++)
    25         for (int i=1;i<=n-len;i++)
    26         {
    27             const int j=i+len;
    28             f[i][j][0]=min(inf,min(f[i+1][j][0]+(n-j+i)*(a[i+1]-a[i]),f[i+1][j][1]+(n-j+i)*(a[j]-a[i])));
    29             f[i][j][1]=min(inf,min(f[i][j-1][0]+(n-j+i)*(a[j]-a[i]),f[i][j-1][1]+(n-j+i)*(a[j]-a[j-1])));
    30         }
    31     printf("%d
    ",min(f[1][n][0],f[1][n][1]));
    32     return 0;
    33 }
    View Code

     此题在九月份错过一次。

    BZOJ1694一样哦!然而又错了,一看原题一激动忘排序了。

  • 相关阅读:
    ArcSDE安装报 “contains an incorrect path”
    vs对话框"发生生成错误,是否继续并运行上次的成功生成"的设置
    修改XML节点名称
    git 常用
    mysql 执行sql流程
    DocumentBuilderFactory.newInstance() 异常解决
    samba 配置
    ajax jquery
    c++ map
    javacc jjtree 写法 以及 jj写法 基本语法 以及应用
  • 原文地址:https://www.cnblogs.com/Blue233333/p/7471774.html
Copyright © 2011-2022 走看看