当前位置: 首页 > news >正文

AtCoder - arc058_d Iroha Loves Strings解答与注意事项

链接:Iroha Loves Strings - AtCoder arc058_d - Virtual Judge

利用bitset这一数据结构,定义bitset类型的变量dp[i]表示第i到n个字符串能拼成的字符串长度都有哪些,比如00100101,表示能拼成的长度有0,2,5,(注意:bitset中的元素从右往左看,下标从0开始),利用递推关系更新dp[i]如下
dp[i] = dp[i+1] | (dp[i+1] << s[i]的长度)
若dp[i][k] = 1,说明第i到第n个字符串可以拼成长度为k的字符串


之后模拟取数,i从1到k进行遍历,每次取当前能取的最小的字符,具体实现方式如下:(以下描述建议结合代码看)


定义候选对数组 pair<int,int> sel[i][j],i为0或1(用作开关变量),j是候选对象的编号,从1到cnt或ncnt,每个sel[i][j]中存的是
<候选字符所在的字符串的序号,候选字符在该字符串中的下标>
第一个字符的候选字符串i,要满足dp[i+1][k-s[i]的长度] = 1,也就是选了第i个字符串后,之后的字符串必须保证能拼成(k-s[i]的长度)的长度的字符串,将pair<i,0>加入sel


i从1到k遍历,每次在所有候选字符中选择字典序最小的那个字符作为答案,接着分情况讨论:
1.如果字符串还没用完,就继续将该字符串的下一个元素加入候选队列,如果有这样的字符串:
ab和ac,那么b和c都应该加入候选队列,

2.如果有一个字符串用完了,可能出现这样的情况:abc abc,这时应该先选前面的“abc”,因为选完编号为i的字符串后,新入选的字符串的下标从 i+1 开始,如果选了第二个或后面的,就会有字符串没法被用到,从而导致丢失解或错误解,新入选的字符串(编号为 j )要满足dp[ j+1 ][ k-i-新字符串的长度 ]等于1,这样选其能确保最终构成的字符串有可能长度为k,将pair<新字符串的编号,0>加入sel中

复杂度估计:nk

注意:

bitset和pair定义的先后会影响程序运行对错,正确的顺序是先定义bitset后定义pair,原因涉及到C++语言本身

#include<bits/stdc++.h>
using namespace std;const int maxn=2005,maxk=1e4+5;
char s[maxn][maxk];
int len[maxn];
int n,k;
bitset<maxk> dp[maxn];
pair<int,int> sel[2][maxn];//pair和bitset的先后问题int main()
{ios::sync_with_stdio(0);cin.tie(0);//freopen("D:\\in.txt","r",stdin);cin>>n>>k;for(int i=1;i<=n;i++){cin>>s[i];len[i]=strlen(s[i]);}dp[n+1][0]=1;for(int i=n;i>=1;i--){dp[i]=(dp[i+1] | (dp[i+1]<<len[i]));}int cnt=0;//挑出第一个字符的可选对象for(int i=1;i<=n;i++){if(dp[i+1][k-len[i]]){//printf("%d可选\n",i);sel[0][++cnt]={i,0};}}int t=1;for(int i=1;i<=k;i++){int ncnt=0;t^=1;char cur='z';for(int j=1;j<=cnt;j++){cur=min(cur,s[sel[t][j].first][sel[t][j].second]);}cout<<cur;//更新下一组候选对象int minid=n+1;for(int j=1;j<=cnt;j++){int id=sel[t][j].first,pos=sel[t][j].second;if(s[id][pos]!=cur) continue;if(pos<len[id]-1){sel[t^1][++ncnt]={id,pos+1};}else{minid=min(minid,id);       //选序号最小的,这样后面的字符串还能用得上(不然会白白浪费字符串)}}for(int j=minid+1;j<=n;j++){if(k-i-len[j]>=0 && dp[j+1][k-i-len[j]]){sel[t^1][++ncnt]={j,0};}}cnt=ncnt;}return 0;
}

http://www.lryc.cn/news/536132.html

相关文章:

  • 企业使用统一终端管理(UEM)工具提高端点安全性
  • Leetcode 算法题 9 回文数
  • 设计模式Python版 命令模式(上)
  • C语言之循环结构:直到型循环
  • 细说STM32F407单片机RTC的备份寄存器原理及使用方法
  • MATLAB计算反映热需求和能源消耗的度数日指标(HDD+CDD)(全代码)
  • J6 X8B/X3C切换HDR各帧图像
  • 09-轮转数组
  • 用vue3写一个好看的wiki前端页面
  • 瑞芯微烧写工具
  • 说下JVM中一次完整的GC流程?
  • Open FPV VTX开源之OSD使用分类
  • 智慧农业-虫害及生长预测
  • Python 识别图片和扫描PDF中的文字
  • C语言如何知道当前系统中的编译器数据类型的大小是多少?
  • gitlab Webhook 配置jenkins时“触发远程构建 (例如,使用脚本)”报错
  • Mysql中使用sql语句生成雪花算法Id
  • /etc/profile vs ~/.bashrc:如何正确使用?
  • SpringBoot实战:高效获取视频资源
  • Flutter_学习记录_数据更新的学习
  • c++ 多线程知识汇总
  • day09_实时类标签/指标
  • 【前端开发学习笔记16】Vue_9
  • Bash 中的运算方式
  • 2025年3月营销灵感日历
  • MySQL的innoDB引擎
  • HCIA项目实践---OSPF的知识和原理总结
  • hexo 魔改 | 修改卡片透明度
  • 今日AI和商界事件(2025-02-13)
  • 38.日常算法