Gym102916J. Lost Island 博弈论

link
第三场训练赛的题目,很有趣的一个博弈问题
不存在 b i = 0 b_i=0 bi=0 时是关键
题解之后再补吧,今天好忙。

题意

一个岛上的人眼睛颜色有 n n n ( n ≥ 2 ) (n \geq 2) (n2) 种,每种有 a i   ( a i ≥ 1 ) a_i\ (a_i \geq 1) ai (ai1)个,每天中午12点岛上的所有人会来到广场,可以看到其他所有人眼睛的颜色。如果此时有人知道了自己眼睛的颜色,那么他会在第二天的中午12点当众自杀,一开始大家只知道有N种颜色,不知道每种颜色有没有人。
第0天,一位旅行者来到岛上说了 n n n 句真话:
i i i 句话是:岛上至少有 b i b_i bi个人的眼睛颜色是 i i i。( b i ≥ 0 b_i\geq 0 bi0,且至少存在一个 b i > 0 b_i > 0 bi>0)
问:最后会有多少人自杀,以及最后有人自杀是哪一天?

思路

c n t cnt cnt 表示 b i = 0 b_i = 0 bi=0 i i i 的个数,分为cnt = 0, = 1, > 1的三种情况。

  1. cnt>1时,显然所有 bi==0ai都不会自杀,除此之外都自杀了
  2. cnt=1时,bi==0对应的 ai 会在其他所有人自杀后的第二天自杀。
  3. cnt=0时是关键,见代码。

代码

int n;
int a[maxn], b[maxn];
void solve() {
    cin >> n;
    int cnt0 = 0;
    int cnt1 = 0;
    vector<int> c;
    for(int i = 1; i <= n; i++) {
    	cin >> a[i] >> b[i];
    	c.push_back(a[i] - b[i] + 1);
    	if(b[i] == 0) {
    		cnt0++;
    		cnt1+=a[i];
    	}
    }
    ll ans = 0;
    ll ans2 = 0;
    for(int i = 1; i <= n; i++) {
    	if(b[i])
    	{
    		ans = max(ans, a[i]-b[i] + 1);
    		ans2 += a[i];	
    	}
    }
    sort(c.begin(), c.end());
    if(cnt0 == 0) {
    	ans = min(c[n-1], c[n-2] + 1);
    }
    if(cnt0 == 1) {
    	ans++;
    	ans2 += cnt1;
    }
    cout << ans << ' ' << ans2 << endl;
}

你可能感兴趣的:(博弈论,算法)