• HDU--5280(dp或枚举)


    官方题解:
    这个题有非常多O(n2)的算法。这里说一种:枚举每个区间,在枚举区间的同一时候维护区间内的最小值和区间和,将最小值与P的大小进行比較,贪心地取最大值就可以。注意若枚举到的区间是整个数组,则P的值是必须取的。
    当然也存在O(n)的做法:从左往右处理出dp1[i]=max(a[i],dp1[i1]+a[i]),相同从右往左处理出dp2[i]=max(a[i],dp2[i+1]+a[i])。再枚举要改动哪一个数,用两个数组更新答案就可以。
    
    
    我是用了两次dp。事实上能够合成一个的,o(n2)的也是,每改一次dp一次,写的略丑。
    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<map>
    #include<cstring>
    #include<algorithm>
    #define INF 0x3f3f3f3f3f3F
    #define mem(a,b) memset(a,b,sizeof(a))
    using namespace std;
    
    typedef long long ll;
    typedef unsigned long long llu;
    const int maxd=1000+10;
    //---------------------
    ll a[maxd];
    ll dp[2][maxd];
    ll n,p;
    
    ll DP()
    {
    
        dp[0][0]=max(a[0],(ll)0);
        for(int i=1;i<n;++i)
            dp[0][i]=max((ll)0,(ll)dp[0][i-1]+a[i]);
    
       ll ans=a[0];
        for(int i=1;i<n;++i){
              dp[1][i]=dp[0][i-1]+a[i];
              ans=max(ans,dp[1][i]);
        }
    
    
        return ans;
    }
    
    int main()
    {
        freopen("1.txt","r",stdin);
        int kase;
        scanf("%d",&kase);
        while(kase--)
        {
           scanf("%I64d%I64d",&n,&p);
           for(int i=0;i<n;++i)
            scanf("%I64d",&a[i]);
           ll ans=-1000000000001;
           for(int i=0;i<n;++i)
           {
               int tmp=a[i];
               a[i]=p;
               ans=max(ans,DP());
               a[i]=tmp;
           }
           printf("%I64d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    Java
    Java
    Python 浮点数类型的精度问题
    Ubuntu下pip的更新问题
    初章
    第二次结对编程作业
    第一次结对编程作业
    Shengnan的《构建之法》读书笔记
    Backend事后诸葛亮
    ASE Alpha Sprint
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/5307023.html
Copyright © 2020-2023  润新知