• 【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;
    }
    
    
  • 相关阅读:
    CSS3相关编码规范
    WEB开发中常见的漏洞
    Python常用端口扫描
    33、Django实战第33天:我的消息
    32、Django实战第32天:我的收藏
    31、Django实战第31天:我的课程
    30、Django实战第30天:修改邮箱和用户信息
    29、Django实战第29天:修改密码和头像
    28、Django实战第28天:个人信息展示
    27、Django实战第27天:全局搜索功能开发
  • 原文地址:https://www.cnblogs.com/BeautifulWater/p/15999978.html
Copyright © 2020-2023  润新知