1614 Hell on the Markets(貪心 + 結論)
阿新 • • 發佈:2019-02-20
點選開啟題目連結
題目大意
給定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;
}