zoukankan      html  css  js  c++  java
  • hdu4960 区间dp

    由于可以预处理出每个左端点对应的右端点,所以并不需要开二维,复杂度应该是介于n和n^2之间。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #define REP(i,a,b) for(int i=a;i<=b;i++)
    #define MS0(a) memset(a,0,sizeof(a))
    
    using namespace std;
    
    typedef long long ll;
    const int maxn=1000100;
    const int INF=1e9+10;
    
    int n;
    ll a[5010];
    int cost[5010];
    int dp[5010];
    ll ls[5010],rs[5010];
    
    int Find(int x)
    {
        int l=0,r=n+1;
        while(l<=r){
            int m=(l+r)>>1;
            if(rs[m]==ls[x]) return m;
            if(rs[m]<ls[x]) r=m-1;
            else l=m+1;
        }
        return -1;
    }
    int F[5010];
    
    int dfs(int l,int r)
    {
        int &res=dp[l];
        if(~res) return res;
        if(l>r) return res=0;
        res=cost[r-l+1];
        int k2;
        REP(k,l,r-1){
            k2=F[k];
            if(k2==-1||k>=k2) continue;
            res=min(res,cost[k-l+1]+cost[r-k2+1]+dfs(k+1,k2-1));
        }
        return res;
    }
    
    int main()
    {
        //freopen("in.txt","r",stdin);
        while(~scanf("%d",&n)&&n){
            REP(i,1,n) scanf("%I64d",&a[i]);a[0]=a[n+1]=0;
            REP(i,1,n) scanf("%d",&cost[i]);
            ls[0]=0;REP(i,1,n) ls[i]=ls[i-1]+a[i];
            rs[n+1]=0;for(int i=n;i>=1;i--) rs[i]=rs[i+1]+a[i];
            REP(i,1,n) F[i]=Find(i);
            memset(dp,-1,sizeof(dp));
            printf("%d
    ",dfs(1,n));
        }
        return 0;
    }
    View Code
    没有AC不了的题,只有不努力的ACMER!
  • 相关阅读:
    四则运算结对作业
    读《构建之法》第四、十七章有感
    四则运算练习的命令行软件
    Spring01
    oop01
    运行shell脚本的三种方式
    正则表达式的基础组成部分
    C语言文件函数
    shell文件描述符及重定向
    shell基础
  • 原文地址:https://www.cnblogs.com/--560/p/5354545.html
Copyright © 2011-2022 走看看