AtCoder Beginner Contest 382 赛后复盘

abc381 的赛后总结不见了。(人话:没写)

A - B

模拟即可

C

因为好吃的会被前面的人吃掉,后面的人只能捡垃圾吃,所以实际上能吃东西的 \(a\) 成单调递减。
所以我们直接二分在哪个区间即可,时间复杂度 \(O(m \log n)\)

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 200050
int n,m;
int a[maxn],b[maxn];
int x[maxn],top,X[maxn],idx[maxn],IDX[maxn];
int ans[maxn];
void work() {
	in2(n,m);
	For(i,1,n) in1(a[i]);
	For(i,1,m) in1(b[i]);
	x[++top]=a[1];
	idx[top]=1;
	int mx=a[1];
	For(i,2,n) if(a[i]<mx) {
		x[++top]=a[i];
		idx[top]=i;
		mx=a[i];
	}
	idx[top+1]=-1;
	For(i,1,m) {
		cout<<idx[lower_bound(x+1,x+top+1,b[i],greater<int>())-x]<<'\n';
//		if(b[i]<X[top]) cout<< -1<<' ';
//		else cout<<IDX[lower_bound(X+1,X+top+1,b[i])-X]<<' ';
	}
}

signed main() {
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	int _=1;
//	int _=read();
	For(i,1,_) {
		work();
	}
	return 0;
}

D

简单搜索剪枝。
因为 \(a_{i-1} + 10 \le a_i\),所以如果 \(a_i\) 能填 \(x\) 时必须有 \(x+(n-i)\times 10 \le m\)
然后搜索即可。

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 15
int n,m;
int a[maxn];
int ans=0;
void dfs(int pre,int now,bool flg) {
	if(now==n+1&&flg) {
		For(i,1,n) cout<<a[i]<<' ';
		puts("");
		return ;
	} else if(now==n+1){
		ans++;
		return ;
	}
	For(i,0,m) {
		a[now]=a[now-1]+10+i;
		if(a[now]+10*(n-now)<=m) dfs(pre+a[now],now+1,flg);
	}
}
void work() {
	in2(n,m);
	a[0]=-9;
	dfs(0,1,0);
	cout<<ans<<'\n';
	dfs(0,1,1);
}

signed main() {
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	int _=1;
//	int _=read();
	For(i,1,_) {
		work();
	}
	return 0;
}

E

我不会期望 dp。
因为一次抽一包一定会抽出正整数张卡,我们不妨算出抽一包能抽出多少张卡的概率。
我们设 \(val_{i,j}\) 表示抽到第 \(i\) 张卡时出了 \(j\) 张稀有卡,那么我们有 \(val_{i,j}=val_{i-1,j}\times (1-p_i)+val_{i-1,j-1}\times p_i\),发现只会用到上一维,不妨滚动数组减轻压力(虽然不会有多大影响)。
然后我们设 \(f_{i}\) 表示抽出 \(i\) 张卡的期望次数。\(f_0=0\),原因显然。
于是我们有 \(f_i=(\sum_{j=0}^{\min(i,n)} f_{i-j}*val_{n,j})+1\)
因为 \(f_i\) 的转移会用到 \(f_i\),我们将关于 \(f_i\) 的东西移项过来,得 \((1-val_{n,0})f_i=(\sum_{j=1}^{\min(i,n)} f_{i-j}*val_{n,j})+1\)
再把系数挪过去,有 \(f_i = \frac{(\sum_{j=1}^{\min(i,n)} f_{i-j}*val_{n,j})+1}{1-val_{n,0}}\)
\(n,x\) 同阶,时间复杂度显然 \(O(n^2)\)

点击查看代码
#include<bits/stdc++.h>

#define ll long long
#define i128 __int128

#define mem(a,b) memset((a),(b),sizeof(a))
#define m0(a) memset((a),0,sizeof(a))
#define m1(a) memset(a,-1,sizeof(a))
#define lb(x) ((x)&-(x))
#define lc(x) ((x)<<1)
#define rc(x) (((x)<<1)|1)
#define pb(G,x) (G).push_back((x))
#define For(a,b,c) for(int a=(b);a<=(c);a++)
#define Rep(a,b,c) for(int a=(b);a>=(c);a--)
#define in1(a) a=read()
#define in2(a,b) a=read(), b=read()
#define in3(a,b,c) a=read(), b=read(), c=read()

using namespace std;

int read() {
	int x=0,f=1; char c=getchar();
	for(;c<'0'||c>'9';c=getchar()) f=(c=='-'?-1:1); 
	for(;c<='9'&&c>='0';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
	return x*f;
}
void write(int x) { if(x>=10) write(x/10); putchar('0'+x%10); }

const int mod = 998244353;
int qpo(int a,int b) {int res=1; for(;b;b>>=1,a=(a*a)%mod) if(b&1) res=res*a%mod; return res; }
int inv(int a) {return qpo(a,mod-2); }

#define maxn 5050
int n,m;
double p[maxn];
double val[2][maxn];
double f[maxn];
void work() {
	in2(n,m);
	For(i,1,n) {
		int x=read();
		p[i]=x/100.0;
	}
	val[0][0]=val[1][0]=1;
	For(i,1,n) {
		For(j,0,i) {
			if(j!=0)val[i&1][j]=val[(i-1)&1][j-1]*p[i]+val[(i-1)&1][j]*(1-p[i]);
			else val[i&1][0]=val[(i-1)&1][0]*(1-p[i]);
		}
	}
//	For(i,0,n) cout<<val[n&1][i]<<' '; puts("");
	For(i,1,m) {
		For(j,1,min(i,n)) f[i]+=f[max(i-j,0)]*val[n&1][j];
		f[i]+=1;
		f[i]/=(1-val[n&1][0]);
	}
	printf("%.12lf",f[m]);
}

signed main() {
//	ios::sync_with_stdio(false); 
//	cin.tie(0); cout.tie(0);
	int _=1;
//	int _=read();
	For(i,1,_) {
		work();
	}
	return 0;
}
posted @ 2024-11-30 22:32  coding_goat_qwq  阅读(143)  评论(0编辑  收藏  举报