1. 程式人生 > >1614 Hell on the Markets(貪心 + 結論)

1614 Hell on the Markets(貪心 + 結論)

點選開啟題目連結
題目大意
給定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; }