ABC263
ABC263
VP
score | A | B | C | D | E | F | G |
---|---|---|---|---|---|---|---|
105:02 | 0:24 | 4:11 | 15:03 | 38:49 | 85:02 | ||
+4 | +1 | +1 | +2 |
rk:
perf:
A、B
忽略。
C
就是记一下 next_permutation
这个函数。
或者爆搜也行。
code
void work(){
cin>>n>>m;vi f;
L(i,1,n) f.pb(0);
L(i,1,m-n) f.pb(1);
do{
L(i,0,m-1) i(!f[i])
cout<<i+1<<" ";
cout<<'\n';
}while(next_permutation(all(f)));
}
D
稍微分类讨论一下,把问题转化成更为更加可解的情况。
- 如果整个数组 都被覆盖
此时答案显然是 。
- 如果数组不是完全覆盖
中间必然有一段 没有被改变。
考虑一个前缀和数组 ,此时的答案为
所以枚举左端点 和后缀最小和 并更新答案即可。
code
void work(){
cin>>n>>x>>y;
L(i,1,n) cin>>a[i],s[i]=a[i]+s[i-1];
R(i,n,0){
sum=min(sum,s[i]+y*(n-i));
ans=min(ans,x*i-s[i]+sum);
}cout<<ans;
}
E
期望 DP,倒推。
设 表示在位置 时的期望投掷次数。
对于 DP 的初始状态,显然有 。
当前转移到的 ,可以推得状态转移方程:
但是这样转移的过程中会产生自环,因为等式左右两边都有 这一项。
所以移项消掉右边的 ,得到:
那个 的部分显然可以用后缀和优化转移,这样就解决了。
时间复杂度:
code
void work(){
cin>>n;vector<Z>a(n*2,0),f(n*2,0),s(n*2,0);
L(i,1,n-1) cin>>a[i];f[n]=0;
R(i,n-1,1){
Z res=s[i+1]-s[i+1+a[i].val()];
f[i]=(a[i]+1+res)/a[i];s[i]=s[i+1]+f[i];
}cout<<f[1];
}//取模结构体Z可以翻我的缺省源
F
题目相当于给出了一棵 层的满二叉树。
最底下一层刚好对应 的人。
从最上层开始向下转移。
枚举所有左右子树胜利的情况,取其中 值即可。
同时记录当前状态下的连胜场次数,遍历到最底层时直接返回贡献即可。
显然可以记忆化搜索。
时间复杂度:。
code
const int N=(1<<17)+100,INF=1e9;
int n,c[N][20],f[N][20];
int dfs(int p,int w){
if(p>=(1<<n)) return c[p^(1<<n)][w];if(~f[p][w]) return f[p][w];
return f[p][w]=max(dfs(lc,w+1)+dfs(rc,0),dfs(lc,0)+dfs(rc,w+1));
}void work(){
cin>>n;L(i,0,((1<<n)-1)) L(j,1,n) cin>>c[i][j];
me(f,-1);cout<<dfs(1,0);
}
G
蒟蒻只会网络流做法。
本题的网络流建模方法其实不止一种,这里会提到两种。
建模一
考虑拆点,每个 对应的点 拆成入点 和出点 ,分别向源点和汇点连容量为 的边。
枚举所有组合情况,如果满足和为质数,其入点向出点连边即可。
最后结果除二就是答案。
code
void work(){
cin>>n;vi a(n),b(n);
F.st=n*2+1,F.ed=n*2+2;
es(10000000);
L(i,0,n-1){
cin>>a[i]>>b[i];
F.I(F.st,i,b[i]);
F.I(i+n,F.ed,b[i]);
}L(i,0,n-1) L(j,0,n-1)
if(f[a[i]+a[j]]) F.I(i,j+n,INF);
cout<<F.dinic()/2;
}
建模二
赛时做法,无比愚蠢。
先忽略 ,不拆点,按上面的方法建图。
得到最大流之后引入新的汇点,把之前的汇点和 连上去。
再次跑出最大流,加上剩余的除二即可。
但确实愚蠢了不少。
code
void work(){
cin>>n;vi a(n),b(n);
L(i,0,n-1){
cin>>a[i]>>b[i];
if(a[i]==1) c1=b[i],b[i]=0;
}m=*max_element(all(a))*2;
es(10000000);
L(i,0,n-1)
if(a[i]&1) F.I(i,n+1,b[i]);
else{
F.I(n,i,b[i]);
L(j,0,n-1) if((a[j]&1)&&f[a[i]+a[j]])
F.I(i,j,INF);
}
F.st=n,F.ed=n+1;a1=F.dinic();
F.I(n+2,n+1,c1);L(i,0,n-1)
if(a[i]%2==0&&f[a[i]+1]) F.I(i,n+2,INF);
a2=a1+F.dinic();
ans=a2+(c1-(a2-a1))/2;
cout<<ans;
}
Ex
二分+计算几何?
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下