CSP模拟4
A.最长上升子序列
要求字典序最小,直接贪心。
先在1~k-1 序列1构造,每次在原序列右边放上未被选的数的比它小的数。
剩下的a[k]和未被选的数倒叙输出,即可保证字典序最小。
B.独特序列
一开始题都没读懂,样例1都没想明白
样例1
3
1 2 1
因为(1) 是可以选\(i=1和i=3\)所以不可以单选(1),但可以选(1,1),因为要满足序号递增。
设 \(dp[i]\) 是前 \(i\) 个以 \(a[i]\) 结尾的独特序列的数量。\(last _{a[i]}\) 是 $ a[i] $上一次出现的位置,显然 \(last _{a[i]}\) 之前的不可选。所以其会有 $ last[i] $ 以后的更新到。拿个树状数组维护前缀和就好了。
C.最大GCD
离正解就差个前缀和……
如果 \(k\) 足够的就可以把序列都更新到大于等于最大值的一个数。
如果 \(k\) 不足够大直接暴力枚举 gcd 算出所有的数做出的贡献与 \(k\) 进行比较。
搜挂了。
状压DP.
先贪心考虑。。。 我们把 1~k 挪到一起然后算一个逆序对。
$ f _{i,s} $ 是第 $ i $ 位,状态为 $ j $ 的 次数。一个位置可以选可以不选
选贡献为逆序对,不选贡献为min(左边移到右边,右边移到左边)的步数。
对于逆序对因为要满足单调递增所以可以用sumlow[s>>a]来算。
Code
for(int i=1;i<=n;i++){
int a=read();
int M=1<<(a-1);
for(int j=m;j>=0;j--){
if(!(M&j)){
dp[M|j]=min(dp[M|j],dp[j]+sum[j>>a]);
}
dp[j]=dp[j]+min(sum[j],sum[m-j]);
}
ans=min(ans,dp[m]);
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义