• 【DP】【最大子段和】C. Functions again&D. Yet Another Subarray Problem


    【DP】【最大子段和】C. Functions again&D. Yet Another Subarray Problem

    • 思想:
    • 从头加到尾巴,如果中间加上了一个正数,那就保留下来;而如果加上了一个负数,分两种情况,一种是加上负数后,使得总的和还是大于0,那么还是得加上这个负数,因为仍然残存着余温,后面的数字借助前面的“余温”甚至可以得到更大的子段和。而如果加上后总和小于0的话,那么不如及时止损,另起炉灶。

    C. Functions again

    题目经过了特殊的处理

    相当于在正负正负或者负正负正这两种类型的序列中求一个最大的子段和。

    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    using namespace std;
    const int N = 3E5+5,M = 6E5+10;
    int n,m,a[N],dp[N][2];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n;
        repd(i,1,n) cin>>a[i];
    	repd(i,1,n-1)
    	    if(i&1) dp[i][0] = abs(a[i+1]-a[i]) , dp[i][1] = -dp[i][0];
    		else dp[i][0] = -abs(a[i+1]-a[i]) , dp[i][1] = -dp[i][0];
    	ll maxn = -2e18,cura = 0, curb = 0;
    	repd(i,1,n-1) 
    	{
    		cura += dp[i][0], curb += dp[i][1];
    		if(cura<0) cura = 0;
    		if(curb<0) curb = 0;
    		maxn = max({cura,curb,maxn});
    	}
    	cout<<maxn;
        return 0;
    }
    
    

    D. Yet Another Subarray Problem

    • 依题意得长度为1到m需要减去一个k,而长度为m+1到2m需要再减去一个k,以此类推。
    • 由于m很小,所以可以作为dp的一个状态
    • dp[i][j]表示为考虑到前i位,长度对m取余的结果为j-1的状态的最大价值。
    #include <bits/stdc++.h>
    #define ll long long
    #define ull unsigned long long
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define MAX 1000005
    #define MOD 1000000007
    using namespace std;
    const int N = 3E5+5,M = 6E5+10;
    ll n,m,k,a[N];
    ll dp[N][15];
    int main()
    {
        ios::sync_with_stdio(false);
        cin.tie(0);
        cout.tie(0);
        cin>>n>>m>>k;
        repd(i,1,n) cin>>a[i];
        ll maxn = 0;
        repd(i,1,m) dp[0][i]=-(1ll<<60);
        repd(i,1,n)
            repd(j,1,m)
            {
                if(j==1) dp[i][j] = max(dp[i-1][m],0ll) + a[i] - k;
                else dp[i][j] = dp[i-1][j-1] + a[i];
                maxn = max(maxn,dp[i][j]);
    		}
    	cout<<maxn;
        return 0;
    }
    
    
  • 相关阅读:
    Python下用Tkinter进行GUI编程
    6月3日——回首一个半月
    Consistent Hashing算法
    学生终究要面对社会
    MySQL的锁(1)
    Memcached笔记之分布式算法(idv2.com)
    4月21日总结
    2012.3.29小结
    C#调用c++创建的dll
    以post方式发送文档到端口
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15999978.html
Copyright © 2020-2023  润新知