专栏文章
题解:P14360 [CSP-J 2025] 多边形 / polygon(民间数据)
P14360题解参与者 1已保存评论 0
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 0 条
- 当前快照
- 1 份
- 快照标识符
- @minfqpt8
- 此快照首次捕获于
- 2025/12/02 01:40 3 个月前
- 此快照最后确认于
- 2025/12/02 01:40 3 个月前
思路:
知识点:化归 + 截断背包。
把长度升序排好 。任取可行方案,设其中最大棒是 ,可行条件
,
于是答案变为对每个 :在 中选若干根,其和大于 的子集个数之和。注意因为都不大于 ,单根不可能大于 ,所以无需再显式排除选 根。
设 。用 计数背包维护前缀集合的子集和分布 (只保留 ),以及总子集数 。( 为已处理根数),对于当前最大棒 ,设 为 在所有当前能拼出的子集和里,满足 的那些子集的数量,则所需个数为 。
然后把 加入背包:倒序转移 (若 直接忽略,因为这些和以后对任何阈值 都必然计入“大于阈值”的部分,已经通过 体现),并令 。
时间复杂度 ,最劣时间复杂度 ,空间复杂度 。足以通过本题。
代码:
CPP#include<bits/stdc++.h>
using namespace std;
const int maxn=5005,mod=998244353;
int a[maxn],f[maxn];
int main(){
int n;
cin>>n;
int mx=0;
for(int i=1;i<=n;i++){
cin>>a[i];
mx=max(a[i],mx);
}
sort(a+1,a+n+1);
f[0]=1;
int tot=1,ans=0;
for(int i=1;i<=n;i++){
int lim=a[i],s=0;
for(int t=0;t<=lim;t++){
s+=f[t];
if(s>=mod) s-=mod;
}
int add=tot-s;
if(add<0) add+=mod;
ans+=add;
ans%=mod;
for(int t=mx;t>=0;t--){
if(f[t]){
int u=t+a[i];
if(u>mx) continue;
int v=f[t]+f[u];
v%=mod;
f[u]=v;
}
}
tot<<=1;
tot%=mod;
}
cout<<ans%mod;
return 0;
}
相关推荐
评论
共 0 条评论,欢迎与作者交流。
正在加载评论...