您的位置:首页 > 其它

UVA1614 - Hell on the Markets

2016-01-30 13:22 405 查看
*这道题主要是先证明对任意sum[i]都可以由a1…ai的部分和表示出或者全部。

证明:1.对于k == 1,sum[k]由a1表示出

2。假设对于任意k > 1成立,则sum[k]可有a1…ak中的数字之和表示出。那么sum[k+1] = sum[k] + a[k+1];设1<= p <= a[k+1], 那么sum[k] + p = sum[k] + a[k+1] - (a[k+1] - p);

现在证明sum[k] - (a[k+1] - p)可有a1..ak中的数字之和表示出。因为sum[k] >= k,,并且a[k+1] - p 大于等于零,小于等于a[k+1] - 1,因为a[k+1] <= k+1, 所以0<= a[k+1] - p <= k; 所以0<=sum[k] - (a[k+1] - p) <= sum[k], 因为1..sum[k]中的数可有a1…a[k]部分数之和表示出,所以得证。*

#include <iostream>
#include <queue>
#include <cstdio>
#include <vector>
#include <algorithm>

using namespace std;

struct point{
int num, s, pos;
}op[100005];
int cmp(const point &a, const point &b)
{
return a.num < b.num;
}
int tmp(const point &a, const point &b)
{
return a.pos < b.pos;
}
int main()
{
int n;

while(cin >> n)
{
long long sum = 0;
for(int i = 0; i < n; i++)
{
int m;

scanf("%d", &m);
op[i].num = m;
op[i].pos = i;
op[i].s = 1;
sum += m;

}
if(sum % 2){
cout << "No" << endl;
continue;
}
sort(op, op+n, cmp);
sum /= 2;
for(int i = n-1; i >= 0; i--)
{
if(sum >= op[i].num){
sum -= op[i].num;
op[i].s = -1;
}
if(sum == 0)
break;
}
cout << "Yes" << endl;
sort(op, op+n, tmp);
for(int i = 0; i < n-1; i++)
cout << op[i].s << " ";
cout << op[n-1].s << endl;
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: