zoukankan      html  css  js  c++  java
  • bzoj3315:[Usaco2013 Nov]Pogo-Cow

    思路:首先可以写出n^3dp的状态转移方程:f[i][j]=max{f[j][k]+val[i]},f[i][j]表示最后一步跳到点从j点跳到i点的最大价值(状态不能设成f[i],因为j对后面的决策是有影响的),然后枚举k转移,但这样在时限内是无法通过的,于是考虑如何优化dp,可以改变一下枚举顺序,也就是一般的都是先枚举i再枚举j,可以先枚举j再枚举i,这样有什么好处呢,那么k就以直接用一个指针从j-1扫到1,因为随着i的不断增加,i与j之间的距离是递增的,那么之前合法的决策现在也一定合法,那么就可以用一个值记录最大的f[j][k],转移即可。然后还要记得正反做两遍。

    #include<cmath>
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    using namespace std;
    #define maxn 1005
     
    int n,ans;
    int f[maxn][maxn];
     
    inline int read(){
        int x=0;char ch=getchar();
        for (;ch<'0'||ch>'9';ch=getchar());
        for (;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0';
        return x;
    }
     
    struct node{
        int x,v;
        bool operator <(const node &a)const{return x<a.x;}
    }a[maxn];
     
    int main(){
        n=read();
        for (int i=1;i<=n;i++) a[i].x=read(),a[i].v=read();
        sort(a+1,a+n+1);
        for (int j=1;j<=n;j++){
            int k=j-1,val=f[j][0]+a[j].v;
            for (int i=j+1;i<=n;i++){
                while (k&&a[i].x-a[j].x>=a[j].x-a[k].x)
                    val=max(val,f[j][k]+a[j].v),k--;
                f[i][j]=max(f[i][j],val);
                ans=max(ans,val+a[i].v);
            }
        }
        for (int j=n;j;j--){
            int k=j+1,val=f[j][n+1]+a[j].v;
            for (int i=j-1;i;i--){
                while (k<=n&&a[k].x-a[j].x<=a[j].x-a[i].x)
                    val=max(val,f[j][k]+a[j].v),k++;
                f[i][j]=max(f[i][j],val);
                ans=max(ans,val+a[i].v);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    zzuli-2259 matrix
    【vlan之四种方式链路认证组网]
    【ppp-chap,pap,mp,mp-group】
    【ospf-基础配置】
    【rip-基础配置】
    【静态路由】
    【nat---basic,napt,easy ip】
    【acl-访问控制列表】
    【交换接口的-绑定-认证-隔离】
    【vlan-给予mac地址认证】
  • 原文地址:https://www.cnblogs.com/DUXT/p/6044492.html
Copyright © 2011-2022 走看看