zoukankan      html  css  js  c++  java
  • [hdu4960]Another OCD Patient(区间dp)

    题意:给出n个数,把这n个数合成一个对称的集合。每个数只能合并一次。

    解题关键:区间dp,dp[l][r]表示l-r区间内满足条件的最大值。vi是大于0的,所以可以直接双指针确定。

    转移方程:$dp[l][r] = min (val(r - l + 1),val(r - i + 1) + val(j - l + 1) + dp[j + 1][i - 1])$

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    int dp[5002][5002],v[5002],a[5002];
    ll sum[5002];
    ll dfs(ll L,ll R){
        if(L>=R) return 0;
        if(~dp[L][R]) return dp[L][R];
        ll ans=a[R-L+1],l=L,r=R;
        while(l<r){
            ll sum1=sum[l]-sum[L-1],sum2=sum[R]-sum[r-1];
            if(sum1==sum2){
                ans=min(ans,dfs(l+1,r-1)+a[l-L+1]+a[R-r+1]);
                l++,r--;
            }else if(sum1<sum2) l++;
            else r--;
        }
        return dp[L][R]=ans;
    }
    int main(){
        ll n;
        while(~scanf("%lld",&n)&&n){
            for(int i=1;i<=n;i++) scanf("%d",v+i),sum[i]=sum[i-1]+v[i];
            for(int i=1;i<=n;i++) scanf("%d",a+i);
            memset(dp,-1,sizeof dp);
            ll ans=dfs(1,n);
            printf("%lld
    ",ans);
        }
        return 0;
    }
  • 相关阅读:
    折半枚举(双向搜索)
    弹性碰撞
    集合的整数表示
    反转(开关问题)
    尺取法
    floor函数用法
    二分搜索
    4. 差分约束系统
    二叉树的表达式求值
    关于移动app开发的一些不错的站点
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7804941.html
Copyright © 2011-2022 走看看