UVALive - 4378 Hell on the Markets

Most financial institutions had becomeinsolvent during financial crisis and went bankrupt or were

bought by larger institutions, usually bybanks. By the end of financial crisis of all the financial

institutions only two banks still continue tooperate. Financial markets had remained closed throughout the crisis and nowregulators are gradually opening them. To prevent speculation and to graduallyramp up trading they will initially allow trading in only one financialinstrument and the volume of trading will be limited to i contracts for i-th minute of market operation.

 

Two banks had decided to cooperate with thegovernment to kick-start the market operation. The boards of directors hadagreed on trading volume for each minute of this first trading session. One bankwill be buying ai contracts (1 <=ai<= i) during i-th minute (1 <=i<= n), while the other one will be selling. Theydo not really care whether to buy or to sell, and the outside observer willonly see the volume ai of contracts traded per minute. However, they do not want to take anyextra risk and want to have no position in the contract by the end of thetrading session. Thus, if we define bi = 1 when the first bank is buying and bi = -1when the second one is buying (and the first one is selling), then the requirement for the trading session is that.

 

Your lucky team of three still works in thedata center (due to the crisis, banks now share the data

center and its personnel) and your task is tofind such bi or to report that this is impossible.

Input

The input file contains several test cases,each of them as described below.

The first line of the input contains thesingle integer number n (1 <=n<= 100 000).

The second line of the input contains n integer numbers — ai (1<= ai <=i).

Output

For each test case, the first line of theoutput must contain ‘Yes’ if the trading session with specified

volumes is possible and ‘No’ otherwise. In the former option a second line mustcontain n numbers — bi.

Sample Input

4

1 2 3 3

4

1 2 3 4

Sample Output

No

Yes

1 -1 -1 1

 

题目大意:这道题主要意思是说现在有一个整数序列a(ai<=i),然后找到另一个序列b(bi仅有1和-1这两个元素),似的Σai*bi和为0,若存在bi输出“Yes”并输出序列b,若不存在b,输出“No”。

根据题意,题目可以转化为在a中找到一部分元素,使得这些元素的和为a序列总(记为S)的一半。看到这道题,我的想法是将序列a从大到小排序,然后一次从大到小选择ai,将ai加到sum上,每次都判断sum<S/2;如果sum<S/2则继续加下一个ai,如果sum>S/2则减去ai,如果sum=S/2则加到sum中的ai对应的bi为1,其他为-1,即找到最终结果;如果将a中的元素加玩之后仍未找到sum=S/2则不存在序列b。另外序列a中都为整数,所以当S为奇数时必不存在序列b,可以提前判断。

 

上面这个想法是基于贪心的想法,下面给出这个做法的不严格证明:

首先,由于ai<=i,所以前i个元素a1,a2,a3,~,ai,对于任意的x<i;都可以表示成a1,a2,a3,~,ai中部分元素的和。

例如:a:1 2 3 3 4 4 6 6 6 1011;其中5=4+1=3+2,7=4+3=4+2+1,8=4+4=4+3+1,9=4+4+1=3+3+2+1;

根据上面的结论,如果在算法过程中优先选择较大的ai加到sum中,若sum<S/2且sum+ai>S/2,则S/2-sum<ai<=I,所有S/2-sum可以由其他小于ai的元素组成,但可能存在例如a中只有一个元素的情况,所以算法中从大到小依次加到sum中,直到sum=S/2或者ai用完。

 

代码如下:

 

#include<bits/stdc++.h>
using namespace std;
struct book
{
	int n;//ai值
	int num;//序号
	int flag;//对于的bi值
};
book b[111111];
bool cmp(book b1, book b2)//按值从大到小排序
{
	return b1.n > b2.n;
}
bool cmp2(book b1, book b2)//按序号从小到大排序
{
	return b1.num < b2.num;
}
int main()
{
	int n,i;
	long long sum;
	while(cin>>n)
	{
		sum = 0;
		for(i=0; i<n; i++)
		{
			cin>>b[i].n;
			b[i].num = i;
			b[i].flag=-1;
			sum += b[i].n;
		}
		if(sum%2 != 0)//判断和是否为奇数
		{
			cout<<"No"<<endl;
			continue;
		}
		sort(b, b+n, cmp);
		sum =sum/2;
		for(i=0; i<n; i++)
		{
			if(b[i].n <= sum&&sum>0)
			{
				sum -= b[i].n;
				b[i].flag = 1;
			}
		}
		if(sum == 0)
		{
			cout<<"Yes"<<endl;
			sort(b, b+n, cmp2);
			for(i=0; i<n; i++)
			{
				cout<<b[i].flag<<' ';
			}
			cout<<endl;
		}
		else
			cout<<"No"<<endl;
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值