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;
}
本文来自博客园,作者:coding_goat_qwq,转载请注明原文链接:https://www.cnblogs.com/CodingGoat/p/18579051