AtCoder Beginner Contest 323 - A B C D E(概率 DP)

ABC323

A - Weak Beats

遍历判断偶数位的字符是否都是 '1' 即可

B - Round-Robin Tournament

统计每个人的胜场次数,再按照胜场次数降序,序号升序排序输出即可

C - World Tour Finals

第 i 个人的得分是 过的题的得分和 + 序号 i 的额外分
先统计出每个人的得分,找到最高分,再将原输入的题目按照分数降序排序
判断每个人时,从最高分的题目向最低分的题目遍历,遇到没过的题则加上分数,第一次大于已知最大分退出,加了几次即为答案

D - Merge Slimes

参考题解

一类史莱姆无法合并当且仅当该类史莱姆只有 1 个
而且可以发现一点,对同一类不断的合并的次数不会超过 log 次
因为数字较大,可以利用 map 来统计数字的个数
利用 set 来记录初始的数字,我们可以知道的是,所有的合并起点一定是初始的数字开始的,如果说对每一个初始的数字都合并到不能合并为止,那么沿途的数字肯定都是不能再合并的
最后的答案就是遍历 map 看剩余的数字的个数

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long

using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*

*/
const int maxm = 1e5 + 5, inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353;

void solve(){
	ll n, ans = 0;
	map<ll, ll> cnt;
	cin >> n;
	set<ll> q;
	for(int i = 1; i <= n; ++ i){
		int s, c;
		cin >> s >> c;
		cnt[s] = c;
		q.insert(s);
	}
	for(auto &i : q){
		int sum = 0;
		for(ll j = i; 1; j = j + j){
			sum += cnt[j];
			if(sum < 2){
				cnt[j] = sum; break;
			}
			cnt[j] = sum % 2;
			sum /= 2;
		}
	}
	for(auto &i : cnt){
		ans += i.second;
	}
	cout << ans << '\n';
	return ;
}

signed main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	// cin >> _;
	while(_ --){
		solve();
	}
	return 0;
}

E - Playlist

概率 DP

状态
$dp[i] $ 表示从 i 时刻开始播放音乐的概率

转移
遍历 0 时刻到 x 时刻,枚举每一个音乐
对于时刻 i,$dp[i] = \sum \frac{dp[i - t[j]]}{n}, (i - t[j] \ge 0) $

如果想要在 x + 0.5 的时刻播放音乐 1,那么我们需要在时刻 \([x - t[1] + 1, x]\) 播放音乐 1
故 $ans = \displaystyle \sum_{i = max(0, x - t[1] + 1)} ^{x} dp[i] \times \frac{1}{n} $

//>>>Qiansui
#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define mem(x,y) memset(x, y, sizeof(x))
#define debug(x) cout << #x << " = " << x << '\n'
#define debug2(x,y) cout << #x << " = " << x << " " << #y << " = "<< y << '\n'
//#define int long long

using namespace std;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ull, ull> pull;
typedef pair<double, double> pdd;
/*

*/
const int maxm = 1e4 + 5, inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f, mod = 998244353;
ll n, x, t[maxm], dp[maxm];;

ll qpow(ll a, ll x, ll p){
	a %= p;
	ll res = 1;
	while(x){
		if(x & 1) res = res * a % p;
		x >>= 1;
		a = a * a % p;
	}
	return res;
}

void solve(){
	cin >> n >> x;
	for(int i = 1; i <= n; ++ i){
		cin >> t[i];
	}
	dp[0] = 1;
	for(int i = 0; i <= x; ++ i){
		for(int j = 1; j <= n; ++ j){
			if(i >= t[j]){
				dp[i] = (dp[i] + (dp[i - t[j]] * qpow(n, mod - 2, mod)) % mod) % mod;
			}
		}
	}
	ll ans = 0;
	for(int i = max(0ll, x - t[1] + 1); i <= x; ++ i){
		ans = (ans + dp[i]) % mod;
	}
	ans = ans * qpow(n, mod - 2, mod) % mod;
	cout << ans << '\n';
	return ;
}

signed main(){
	ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
	int _ = 1;
	// cin >> _;
	while(_ --){
		solve();
	}
	return 0;
}
posted @ 2023-10-07 23:56  Qiansui  阅读(160)  评论(0)    收藏  举报