UVA - 1614 Hell on the Markets(贪心 + 结论)

35 篇文章 0 订阅
14 篇文章 0 订阅

点击打开题目链接
题目大意
给定n个数,满足1<=a[i]<=i;
使其中某些数变成倒数使得n个数总和为0;

思路:
结论:n个数可以组成1~sum[n]的任意数
证明:
当n = 1时, a[1] = 1 = sum[1] 满足;
假设当n = k时满足;
当n = k + 1时:
sum[k+1] = sum[k] + a[k+1];
因此只需证明能凑出sum[k]+1 ~ sum[k+1]的所有整数即可。
设p满足1<=p<=a[k+1]
∵sum[k] + p = sum[k] + a[k+1] - (a[k+1] - p);
并且 1<=a[k]<=k
∴sum[k] >= k && a[k+1] - p <= k;
因为前k个数能凑出a[k+1] - p;
∴前n个数能凑出1~sum[n]的所有数。

代码:

#include<bits/stdc++.h>

using namespace std;
const int maxn = 100000 + 5;
typedef long long ll;
struct a{
    int id, x;
    bool operator < (const a & rhs) const {
        return x > rhs.x;
    }
}p[maxn];
int po[maxn];
int n;

int main() {
    //ios::sync_with_stdio(false),cin.tie(0);
    //freopen("D:\\input.txt", "r", stdin);
    //freopen("D:\\output.txt", "w", stdout);
    while(cin >> n) {
        memset(p, 0, sizeof(p));
        memset(po, 0, sizeof(po));
        ll sum = 0;
        for(int i = 0; i < n; i++) {
            cin >> p[i].x;
            p[i].id = i;
            sum += p[i].x;
        }
        if(sum % 2) cout << "No" << endl;
        else {
            cout << "Yes"  << endl;
            sort(p, p + n);
            sum = sum / 2;
            for(int i = 0; i < n; i++) {
                if(p[i].x <= sum) {
                    po[p[i].id] = 1;
                    sum -= p[i].x;
                }
                else po[p[i].id] = -1;
            }
            //cout << po[1] << ' ' << po[2] << ' ' << po[3] << ' ' << po[4] << "QAQ"  << endl;
            for(int i = 0; i < n; i++) {
                if(i == 0) printf("%d", po[i]);
                else printf(" %d", po[i]);
            }
            printf("\n");
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Chook_lxk

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值