【2015-2016 XVI Open CupJ】【DP bitset记录方案】Judgement n人投票前后权威值改变是否有实际区别

J. Judgement
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

The jury of Berland regional olympiad in informatics does not trust to contest management systems, so the Berland regional programming contest is judged by the next way. There are n judges in the jury, each judge have authority ai. When jury receives a diskette with the new solution, each jury member reads its source and votes "OK" or "WA". If after the voting ends the sum of authorities of jury members, who think that solution is correct, is equal or greater to p, then soluton is accepted, otherwise it is rejected.

Several jury members think, that current system is too complicated for them and proposed some changes: each jury member will have new authority bi, and limit is changed to q; then, in their opinion, calculations will be easier, and nothing more changes.

You are hired by the Department of Education of Berland region to check if the new system is equivalent to old one, i.e. that at any possible distribution of votes final verdict with the new and with the old parameters will be the same. If the systems differ, output an example of voting, when verdicts in both systems are different.

Input

First line of the input contains one integer n (1 ≤ n ≤ 100) — number of judges in the jury.

Second line contains n + 1 integers p, a1, a2, ..., an (1 ≤ p, ai ≤ 106) — the current acception limit and the current values of authorities of jury members, respectively.

Third line contains n + 1 integers q, b1, b2, ..., bn (1 ≤ q, bi ≤ 106) — the new acception limit and the new values of authorities of jury members, respectively.

Output

If old and new systems are equivalent, print "YES". Otherwise in the first line of output print "NO", and in second print example of voting, with different verdicts in old and new systems. Voting is encoded with the string of length n, where i-th character is '1', if i-th judge considered solution correct and '0' otherwise.

If several answers are possible, print any of them.

Examples
input
3
8 4 5 6
2 1 1 1
output
YES
input
3
6 4 5 6
2 1 1 1
output
NO
001

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<string>
#include<ctype.h>
#include<math.h>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
void fre() { freopen("c://test//input.in", "r", stdin); freopen("c://test//output.out", "w", stdout); }
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }
template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }
const int N = 1e6 + 10, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int n;
int v[2];
int a[2][105];
int f[N];
bitset<101>d[N];
bool solve(int o)
{
	MS(f, 63); f[0] = 0;
	int top = 0;
	for (int i = 1; i <= n; ++i)
	{
		for (int j = top; j >= 0; --j)
		{
			int x = min(j + a[o][i], v[o]);//下一个我方状态点
			int y = min(f[j] + a[o ^ 1][i], v[o ^ 1]);//下一个对方状态点
			if (y < f[x])
			{
				f[x] = y;
				d[x] = d[j];
				d[x][i] = 1;
			}
		}
		top = min(top + a[o][i], v[o]);
		if (f[v[o]] < v[o ^ 1])
		{
			puts("NO");
			for (int i = 1; i <= n; ++i)printf("%c", d[v[o]][i] ? '1' : '0');
			puts("");
			return 1;
		}
	}
	return 0;
}
int main()
{
	while (~scanf("%d", &n))
	{
		scanf("%d", &v[0]);
		for (int i = 1; i <= n; ++i)scanf("%d", &a[0][i]);
		scanf("%d", &v[1]);
		for (int i = 1; i <= n; ++i)scanf("%d", &a[1][i]);
		if (!solve(0) && !solve(1))puts("YES");
	}
	return 0;
}
/*
【trick&&吐槽】
1,TLE了不一定是时间不够,可能是死循环了。
2,前驱记录输出方案的方法一定要顾忌到是否存在环
3,状压真是好用,bitset真是好用

【题意】
有n(100)个法官。
每个人有一个权威性a[],
对于一次投票,如果投展成票人数的权威性之和>=p,那么就认为投票有效,否则无效。
然而,这些人的权威性被改变成了b[],决定投票有效与否的数值也由p变成了q。

然后问你,前后的改变是否有实际区别。
如果有,输出同样的投票对应不同的结果的投票方案。

各种与权威性相关的数值a[]、b[]、p、q都在[1,1e6]范围。

【类型】
DP bitset

【分析】
首先,一道题的入手要考虑复杂度。
这道题我们有人数为n(100),各种权威性的值都在1e6,
于是,有一个2e8复杂度的显然正确的方法。
我们发现,出现了实际区别,意味着——
一种投票方案下,对应的权威值尽可能大时,
在另外一种投票方案下,对应的权威值却尽可能小。

不妨先假设p达标,q不达标
于是,我们用f[i][j]表示——
前i个人参与投票,当投票对应的a[]的权威值为j时,所对应的最小b[]
那么有状态转移——
gmin(f[i+1][j+a[i]],f[i][j]+b[i])
然而j+a[i]与f[i][j]+b[i]都可能爆炸。
我们只要控制两者的上限不超过p和q即可(因为实际意义都相同)
最后只要检测f[p]是否<q即可。
还有p不达标q达标的情况,我们对应着也DP一遍。

然而,最后我们还要输出具体的方案。
这个怎么做呢?
一种比较常见的做法,是在每个f[i][j]的j下标对应前驱。
然而,在达到顶端p的时候,这个j有可能指向自己,这样就GG了。
而里面所存的数值,更不能所有前溯的指标。

于是,我们需要用一种特殊的记录方法——
我们观察到,人数n只有100,100虽然超出了状压的范围,
然而还是可以用分开状压(2个LL)或者用bitset存储记忆这个状态是由哪些人贡献来的。
这样我们只要拆分d[p]就可以输出答案了。

【时间复杂度&&优化】
O(n*1e6)

*/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值