SP8284 WEIGHT - Weighted Sum

题意描述

给出长度为n(n<=1e6)的序列A, A中元素可能为正数,可为负数或0,。让你构造一个长度为n的序列W,给这些整数A赋权,使它们的加权和最大化。权重W应满足以下条件:

  • 每个权重都应该是一个正整数。(W中每个元素都是正数)

  • W[1]=1

  • 对于i>1,W[i]应在范围[2,W[i-1]+1]内。(

    W[i] ∈[2,W[i-1]+1] (i>1))

让你构造一个满足这样条件的序列W, 使得ΣA[i]×W[i]最大

输入格式

有多组数据。

第一行数据组数

每组数据第一行为n,后面是n行,每行一个A[i]

输出格式

对于每组数据,输出一行最大加权和;

输入样例

1
4
1
2
3
-4

输出样例

6

翻译:So_what

分析(by Chelly)

简单地分析下W数组的性质

对于那些负数A[i], 为了让总和最大, 我们肯定希望W[i]越小越好, 2是最好的。

对于连续的一串正数A[l..r], 我们肯定希望W[l..r]越大越好, 那么肯定是依次是2 3 4 5 6 ... r-l+2

那么是不是对于每个负数A[i], 对应的W[i]就是2; 对应连续的一串正数, W[i]就是2 3 4 5.....这样呢?

看这样的例子: A[4]={-1,-2,2,10000} 那么W[4]={2,3,4,5}比W[4]={2,2,3,4}更优

我们考虑一串A[l..r], 假设目前的W是2 3 4 5 6....

那么现在的问题的就是对于前面一个A[l-1], 我们究竟要不要将2从W[l-1]开始, 后面的W[l..r]改成3 4 5 6....

注意到如果这样更改, 那么实际上[l,r]对总结果的贡献改变了sum[l..r]

我们肯定希望改变值sum[l..r]是正的

从A序列尾部r向前扫描, 直到扫到一个位置l, sum[l..r]<0, 那么这段位置的W值就依次是2 3 4 5 6 7 ....

将l-1作为新的r往前继续扫描, 直到扫描完整个A序列

为了满足时间复杂度, 需要高效地统计答案

往前扫的过程中, 我们可以假定当前位置是2, 得到目前的ans, 然后如果判定可以向前移动一位, 那么相当于这些位置的W都对应加1, 对于总的结果来说, 就是加上这一段的sum

时间复杂度O(n)

#include<cstdio>
using namespace std;
int T,n,a[1000005];
int main() {
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for (int i=1; i<=n; i++) scanf("%d",&a[i]);
long long ans=0,s=0,sum=0;//ans最大权值和,s当前段的最大权值和,sum当前段的A[]后缀和
for (int i=n; i; i--) {
sum+=a[i];
s+=sum+a[i];//给s+=sum相当于把sum中每个数增加一倍(权值和为正),每个A至少×2,所以s加上两次a[i]
if (sum<0 || i==1) {
if (i==1) s-=sum;//W[1]=1
ans+=s,s=sum=0;//若后缀和变为0,则w[i]取最小2,sum清零
}
}
printf("%lld\n",ans);
}
return 0;
}

题解 SP8284 WEIGHT - Weighted Sum的更多相关文章

  1. PAT甲题题解-1007. Maximum Subsequence Sum (25)-求最大子区间和

    题意:给出n个数,求最大连续的子区间和,并且输出该区间的第一个和最后一个数. 如果所有数都小于0,那么则输出0,第一个数和最后一个数. 看数据k的范围,就知道肯定不能两层for循环来求区间和,O(n^ ...

  2. 『题解』Codeforces121A Lucky Sum

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description Petya loves lucky numbers. Everybody k ...

  3. 题解:UVA10791 Minimum Sum LCM

    原题 题目大意 输入整数\(n(1\le n<2^{31})\) ,求至少两个正整数,是它们的最小公倍数为$ n$,且这些整数的和最小.输出最小的和. 有多组测试输入,以\(0\)结束. 题解 ...

  4. 洛谷 题解 CF910C 【Minimum Sum】

    当时看到这题一脸懵逼,莫名想到了复杂度为O(10000000000*n)的算法,然而肯定会超时(废话) 算法楼上楼下都说的很清楚了 很明显这题是要用每个字母的权值进行排序.然后依次进行赋值. \(\c ...

  5. LeetCode题解之 Continuous Subarray Sum

    1.题目描述 2.循环计算即可 3.代码 bool checkSubarraySum(vector<int>& nums, int k) { ){ return false ; } ...

  6. LeetCode 题解之Minimum Index Sum of Two Lists

    1.题目描述 2.问题分析 直接是用hash table 解决问题 3.代码 vector<string> findRestaurant(vector<string>& ...

  7. 【题解】Intervals

    题目大意   有\(n\)个区间(\(1 \leq n \leq 200\)),第\(i\)个区间覆盖\((a_{i}, b_{i})\)且有权值\(w_{i}\)(\(1 \leq a_{i} &l ...

  8. 【题解】Sigitseeing Tour

    题目大意 有一张$n$个结点,$m$条混合边的图($1 \leq n \leq 200$,$1 \leq m \leq 1000$),求这张图是否存在欧拉回路. 题解 因为有混合边,所以我们要先给无向 ...

  9. Codeforces Round #326 (Div. 2) B. Pasha and Phone C. Duff and Weight Lifting

    B. Pasha and PhonePasha has recently bought a new phone jPager and started adding his friends' phone ...

随机推荐

  1. C++构造函数和重载函数运算符如何区分

    构造函数和重载函数运算符如何区分: class Distance { private: int feet; int inches; public: Distance(){ feet = ; inche ...

  2. PHP 把秒数转为时分秒格式

    PHP函数 1.gmdate $seconds = 174940;$hours = intval($seconds/); $time1 = $hours."小时".gmdate(' ...

  3. 记录 shell学习过程(1) 超简单的面向过程的2个shell 分区以及创建lvm

    分区 #!/usr/bin/env bash #fdisk /dev/sdb << EOF #n # # # #+600M #w #EOF 创建lvm pvcreate /dev/sdb ...

  4. centOS7中启动MySQL数据库提示: Failed to start mysqld.service: Unit not foundc

    现象: 在centOS7中启动MySQL数据库提示: Failed to start mysqld.service: Unit not found [明明已经安装了,为什么提示不存在呢?] 原因: 在 ...

  5. vs2008编译错误fatal error C1902: 程序数据库管理器不匹配;请检查安装解决

    重装了本本上的Xp系统,如往常一样,升级,装杀毒软件,开发工具.一些进行的非常顺利.然而,在我打开VS2008准备耕作的时候,尽然出现了一邪恶的错误提示:vs2008编译错误fatal error C ...

  6. Razor视图中的@:和语法

    Razor视图中的@:和语法 原创changuncle 最后发布于2016-12-07 17:43:50 阅读数 4456  收藏 展开 在MVC项目中新建视图的时候默认支持ASPX引擎和Razor引 ...

  7. AcWing 两个简单的位运算操作

    //是柱状数组的一个基操作 //返回n的最后一位1:lowbit(n) = n & -n //比如 x=1010 那么返回10 x=101000 返回1000 #include<bits ...

  8. window cmd下常用操作

    创建文件夹 mkdir 创建空文件 type nul>文件名 进入目录 cd 进入分区 分区名 引入文件 当前文件: ./文件名 或 直接文件名 上一级目录文件及上一级目录下子文件:../文件名 ...

  9. bzoj 4827: [HNOI2017]礼物 (FFT)

    一道FFT 然而据说暴力可以水70分 然而我省选的时候看到了直接吓傻了  连暴力都没打 太弱了啊QAQ emmmm 详细的拆开就看其他题解吧233 最后那一步卷积其实我一直没明白 后来画画图终于懂了 ...

  10. 只要没有给String[]数组new 空间,那么他就只是一个引用

    public class Test1 { @Test public void test(){ String[] values = {"good", "morning&qu ...