• D. Maximum Sum on Even Positions(动态规划,思维)


    D. Maximum Sum on Even Positions

    原题链接:传送门

    题目大意

    给定一个数组,你可以交换数组中的任意一个子数组,要求执行一次交换后使得整个数组的偶数位置的元素和达到最大。

    分析

    此题的关键还是在于将新的问题转化为原有的问题模型

    第二次拿到这道题依旧使无从下手,如果来了解过最大连续子段和的问题的得话那么应该会对这个问题有一些启发。通过分析首先我们应该可以知道交换的子数组一定是偶数长度,否则将没有意义。

    那么我们可以将该问题转化一下:

    假设对于1 7 3 4 这个序列

    如果我们交换了 1 7那么可以收获的权值为7 - 1 = 6

    如果我们继续扩大长度交换3 4 那么此时的可以收获的权值为 6 + 4 - 3 = 7

    对于此我们可以将其转化为求解数组b的最大连续子数组和的问题

    b[i] = (a[i] - a[i + 1]) / b[i] = a[i - 1] - a[i]

    AC 代码

    AC code

    void slove()
    {
    	int n;cin >> n;
    	ll res = 0;
    	vector<ll> b , c;
    	for(int i = 0;i < n ;i ++)
    	{
    		cin >> a[i];
    		if(i % 2 == 0)res += a[i];
    	}
    	for(int i = 1;i < n ;i += 2)b.PB(a[i] - a[i - 1]);
    	for(int i = 2;i < n ;i += 2)c.PB(a[i - 1] - a[i]);
    	ll sum = -1e9, ans = 0;
    	for(int i = 0;i < b.size() ;i ++)
    	{
    		if(sum > 0)sum += b[i];
    		else sum = b[i];
    		ans = max(ans , sum);
    	}
    	sum = -1e9;ans = max(ans , sum);
    	for(int i = 0;i < c.size() ;i ++)
    	{
    		if(sum > 0)sum += c[i];
    		else sum = c[i];
    		ans = max(ans , sum);
    	}
    	cout << ans + res << endl;
    }
    

    标程/优秀代码

    void slove()
    {
    	int n;cin >> n;
    	vector<int> a(n + 1);
    	ll ans = 0 ,sum1 = 0,sum2 = 0,mx = 0;
    	REP(i , 1 , n)
    	{
    		cin >> a[i];
    		if(i % 2 == 1)ans += a[i];
    	}
    	for(int i = 2;i <= n;i += 2)
    	{
    		sum1 = max((ll)0 , a[i] - a[i-1] + sum1);
    		mx = max(mx , sum1);
    	}
    	for(int i = 3;i <= n;i +=2)
    	{
    		sum2 = max((ll)0 , a[i-1] - a[i] + sum2);
    		mx = max(mx , sum2);
    	}
    	cout << ans + mx << endl;
    }
    
  • 相关阅读:
    在 2016 年学 JavaScript 是一种什么样的体验?
    在 2016 年学 JavaScript 是一种什么样的体验?
    Oracle数据库,内置函数小结
    Oracle数据库,内置函数小结
    Oracle数据库,内置函数小结
    Oracle数据库,内置函数小结
    Bogon
    Bogon
    MariaDB Galera Cluster集群优缺点
    如何设置jquery的ajax方法为同步
  • 原文地址:https://www.cnblogs.com/wlw-x/p/13632442.html
Copyright © 2020-2023  润新知