题解 [ARC132C] Almost Sorted
做这道题的时候注意到了同名题目 CF1730F Almost Sorted,没想到都是状压 DP。
题意
参见题意翻译。
分析
设
如果第
否则就枚举每一个可能的位置,再从上一个进行转移即可。
因为不好描述具体实现就看代码吧,时间复杂度
代码
//the code is from chenjh
#include<cstdio>
#include<cmath>
using namespace std;
const int mod=998244353;
int n,d,a[505],p[505];
int f[505][1<<11];
int main(){
scanf("%d%d",&n,&d);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
if(~a[i]){
p[a[i]]=i;
if(abs(a[i]-i)>d) return puts("0"),0; //已经确定的不符合条件直接判无解。
}
}
**f=1;
for(int i=1,mS=1<<(d<<1|1);i<=n;i++)
if(p[i])for(int S=0;S<mS;++S){
bool fl=1;
for(int j=-d;j<=d;j++)if((i+j<1||i+j>n||~a[i+j])&&((S>>(j+d))&1)){fl=0;break;}//判断是否有被占用的不合法位置。
if(fl)
f[i][S]=(f[i-1][(S<<1)&(mS-1)]+f[i-1][(S<<1|1)&(mS-1)]);//从上一个状态转移,有两种情况。
}
else for(int S=0;S<mS;++S){
bool fl=1;
for(int j=-d;j<=d;j++)if((i+j<1||i+j>n||~a[i+j])&&((S>>(j+d))&1)){fl=0;break;}
if(fl)for(int j=-d;j<=d;j++)if((S>>(j+d))&1)
f[i][S]=(f[i][S]+(long long)f[i-1][((S^(1<<(j+d)))<<1)&(mS-1)]+f[i-1][((S^(1<<(j+d)))<<1|1)&(mS-1)])%mod;
}
int ans=0;
for(int S=0,mS=1<<(d<<1|1);S<mS;++S)ans=(ans+f[n][S])%mod;//将所有情况求和。
printf("%d\n",ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具