UVA-1614 Hell on the Markets(贪心+推理) (有待补充)

题目大意:一个整数序列a,1≤a[i]≤i。问能否通过在一些元素前加上负号,使得整个序列和为0。

题目分析:贪心。贪心策略:每次都先选最大的元素加负号(或保留,不加负号)。

     贪心依据:对于1≤a[i]≤i,1~sum[i]总能表示出来。

       贪心依据证明:用数学归纳法证明,当i=1时,显然成立。假设当i=k时,也成立。当i=k+1时,(先证明到这儿,有空再补)。

 

代码如下:

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
using namespace std;

struct Num
{
    int val,id;
    bool operator < (const Num &a) const {
        return val<a.val;
    }
};
Num num[100005];
int n,mark[100005];

void solve(int u)
{
    for(int i=n-1;i>=0;--i){
        if(u-num[i].val==0){
            mark[num[i].id]=1;
            return ;
        }else if(u-num[i].val>0){
            u-=num[i].val;
            mark[num[i].id]=1;
        }
    }
}

int main()
{
    long long sum;
    while(scanf("%d",&n)==1)
    {
        memset(mark,0,sizeof(mark));
        sum=0;
        for(int i=0;i<n;++i){
            scanf("%d",&num[i].val);
            num[i].id=i;
            sum+=num[i].val;
        }
        if(sum&1){
            printf("No\n");
            continue;
        }
        sort(num,num+n);
        solve(sum/2);
        printf("Yes\n");
        for(int i=0;i<n;++i)
            printf("%d%c",mark[i]?1:-1,(i==n-1)?'\n':' ');
    }
    return 0;
}

  

posted @ 2015-10-12 19:23  20143605  阅读(155)  评论(0编辑  收藏  举报