P7319 「PMOI-4」生成树
题目背景
题目正解不会很难,反正很难的也必不会做,所以宁愿相信题目都是善良的。
——command_block 《考前小贴士》
djy 出了一道生成树的题,然后发现做法假了,就把这个题改了一下,作为这场比赛的 B。
题目描述
给定 nnn 个数,第 iii 个数的原始权值是 wiw_iwi,你要按照某种顺序将这些数依次选择。
若当前是第 iii 次选数,选择的原始权值为 kkk,则其他所有未被选过的数的权值均加上 (−1)i+k+1×k(-1)^{i+k+1} \times k(−1)i+k+1×k。
你需要求出一种选数方案,使得选出的 nnn 个数最终的权值和最大。
输入格式
第一行一个正整数 nnn。
第二行 nnn 个整数 wiw_iwi,表示第 iii 个数的权值。
输出格式
一行一个整数,表示最大权值和。
输入输出样例 #1
输入 #1
7
1 -1 -2 2 -3 3 4
输出 #1
66
说明/提示
【样例解释】
依次选择编号为 {7,6,5,3,4,1,2}\{7,6,5,3,4,1,2\}{7,6,5,3,4,1,2} 的数即可。
【数据范围】
本题采用捆绑测试。
- Subtask 1(20pts):n≤7n \le 7n≤7。
- Subtask 2(30pts):n≤103n \le 10^3n≤103。
- Subtask 3(30pts):保证所有的 wi≥0w_i \ge 0wi≥0 或所有的 wi≤0w_i \le 0wi≤0。
- Subtask 4(20pts):无特殊限制。
对于 100%100\%100% 的数据满足,1≤n≤105,−109≤w≤1091 \le n \le 10^5,-10^9 \le w \le 10^91≤n≤105,−109≤w≤109。
C++实现
#include<bits/stdc++.h>
using namespace std;
namespace Acc{
using ll=long long;
const int N=1e5+9;
int a[N],b[N];
ll r;
void work(){
int n,i,sav=1;
for(cin>>n,i=1;i<=n;++i)cin>>a[i],r+=a[i],a[i]=a[i]*(abs(a[i]%2)==1?1:-1);
for(sav=-1,i=1;i<=n;++i,sav=-sav)b[i]=(n-i)*sav;
sort(a+1,a+n+1),sort(b+1,b+n+1);
for(i=1;i<=n;++i)r+=1ll*a[i]*b[i];
cout<<r<<'\n';
}
}
int main(){return Acc::work(),0;}
后续
接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容