题目链接:
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4489
----------------------------------------------------------------------------------------------------------------------------------
题面不好发,这次就先不发了
比赛的时候死磕dp,最后没推出来,一直没往贪心上想,导致这道签到题没做出来。。。
其实就是先从大到小排序,一个一个加,如果比tot/2,就不加,比他小就加。等于的话就找到了。但这道题贪心的证法还是参考那个博客上的吧。(我太弱了,证不出来~)
上代码:
#include<cstdio> #include<cstring> #include<algorithm> #include<cmath> using namespace std; typedef struct { int num; int id; int sta; } Node; Node node[100010]; bool cmp(Node b,Node c) { return b.num>c.num; } bool cmp2(Node b,Node c) { return b.id<c.id; } int main() { int n; while(scanf("%d",&n)!=EOF) { long long int tot=0; for(int i=0;i<n;i++) { scanf("%d",&node[i].num); node[i].id=i; node[i].sta=-1; tot+=node[i].num; } if(tot%2==1) printf("No\n"); else { sort(node,node+n,cmp); long long int sum=0; for(int i=0;i<n;i++) { if(sum+node[i].num==tot/2) { node[i].sta=1; sum+=node[i].num; break; } else if(sum+node[i].num<tot/2) { node[i].sta=1; sum+=node[i].num; } } if(sum==tot/2) { printf("Yes\n"); sort(node,node+n,cmp2); printf("%d",node[0].sta); for(int i=1;i<n;i++) { printf(" %d",node[i].sta); } printf("\n"); } else printf("No\n"); } } return 0; }