Description

给定一个长度为 \(n\) 的字符串,尽可能包含小写字母,字符 '?' 和字符 ‘*’。保证上面两种特殊字符若出现则一定出现在一个小写字母的后面一位。要求构造一个长度为 \(k\) 的新字符串,它和原串有如下关系:

按照原串的字母顺序向新串中填充,新串中含且仅含小写字母。

若原串的某小写字母后没有特殊字符,则这个字母在新串中必须保留

若原串的某小写字母后有字符 '?',则这个字母在新串中可以被保留,也可以被删除

若原串某小写字母后有字符 '*',则这个字母在新串中可以被保留,可以被删除,也可以被复读很多遍。

Input

第一行是一个长度为 \(n\) 的字符串,保证输入合法

第二行是一个整数 \(k\) 代表要求构造的新串长度

Output

输出一行一个长度为 \(k\) 的字符串,为构造出的串。

若不存在这样的串,输出“Impossible”(不含引号)

Hint

\(1~\leq~n,k~\leq~200\)

Solution

为啥泥萌一个贪心就过了啊qaq,为啥就我一人写了个DP还fst了啊qaq,我咋这么菜啊qaq

我们发现一个字母分别有三种情况:保留,保留/删除,保留/删除/复读。

于是我们处理一个新的字符串,只含给定串中的小写字母,另开数组记录该字母对应哪种情况。一下说的原串均指这个只含小写字母的新串,设原串长度为 \(len\)。

于是问题就被转化为了按照原串一位一位的按照规则填能否填出一个长度为 \(k\) 的字符串。这显然是可以DP的。

其实正着DP大概是可做的,但是比赛的时候有点困就直接倒着DP的。我们设 \(f_{i,j}~=~true/false\) 为能否用原串 \([i,len]\) 位拼出新串的 \([j,k]\) 位。于是转移一共有三种情况:

1、只能保留:

\[f_{i,j}~=~f_{i + 1,j + 1}
\]

2、保留或删除:

\[f_{i,j}~=~f_{i + 1,j + 1}~or~f_{i + 1,j}
\]

3、保留,删除,复读:

\[f_{i,j}~=~f_{i + 1,j + 1}~or~f_{i + 1,j}~or~\bigvee_{h = j + 2}^{k + 1} f_{i + 1, h}~=~\bigvee_{h = j}^{k + 1} f_{i + 1, h}
\]

其中 \(\bigvee_{i = a}^{b} s(i)\) 为若 \(\exists~i_0~\in~[a,b],~s.t.~~s(i_0)~=~true\) 则返回 \(true\),否则返回 \(false\)

初始化为 \(f_{len + 1, k + 1} = true\)

在转移时记录一下转移方向就可以输出方案了。

Code

  1. #include <cstdio>
  2. #ifdef ONLINE_JUDGE
  3. #define freopen(a, b, c)
  4. #endif
  5. #define rg register
  6. #define ci const int
  7. #define cl const long long
  8. typedef long long ll;
  9. namespace IPT {
  10. const int L = 1000000;
  11. char buf[L], *front=buf, *end=buf;
  12. char GetChar() {
  13. if (front == end) {
  14. end = buf + fread(front = buf, 1, L, stdin);
  15. if (front == end) return -1;
  16. }
  17. return *(front++);
  18. }
  19. }
  20. template <typename T>
  21. inline void qr(T &x) {
  22. rg char ch = IPT::GetChar(), lst = ' ';
  23. while ((ch > '9') || (ch < '0')) lst = ch, ch=IPT::GetChar();
  24. while ((ch >= '0') && (ch <= '9')) x = (x << 1) + (x << 3) + (ch ^ 48), ch = IPT::GetChar();
  25. if (lst == '-') x = -x;
  26. }
  27. template <typename T>
  28. inline void ReadDb(T &x) {
  29. rg char ch = IPT::GetChar(), lst = ' ';
  30. while ((ch > '9') || (ch < '0')) lst = ch, ch = IPT::GetChar();
  31. while ((ch >= '0') && (ch <= '9')) x = x * 10 + (ch ^ 48), ch = IPT::GetChar();
  32. if (ch == '.') {
  33. ch = IPT::GetChar();
  34. double base = 1;
  35. while ((ch >= '0') && (ch <= '9')) x += (ch ^ 48) * ((base *= 0.1)), ch = IPT::GetChar();
  36. }
  37. if (lst == '-') x = -x;
  38. }
  39. namespace OPT {
  40. char buf[120];
  41. }
  42. template <typename T>
  43. inline void qw(T x, const char aft, const bool pt) {
  44. if (x < 0) {x = -x, putchar('-');}
  45. rg int top=0;
  46. do {OPT::buf[++top] = x % 10 + '0';} while (x /= 10);
  47. while (top) putchar(OPT::buf[top--]);
  48. if (pt) putchar(aft);
  49. }
  50. const int maxn = 210;
  51. int Len, k, len;
  52. char MU[maxn], CU[maxn];
  53. int pre[maxn][maxn], vc[maxn];
  54. bool frog[maxn][maxn];
  55. void print(ci, ci);
  56. int main() {
  57. freopen("1.in", "r", stdin);
  58. do MU[++Len] = IPT::GetChar(); while (((MU[Len] >= 'a') && (MU[Len] <= 'z')) || (MU[Len] == '?') || (MU[Len] == '*'));
  59. for (rg int i = 1; i <= Len; ++i) if ((MU[i] >= 'a') && (MU[i] <= 'z')) {
  60. CU[++len] = MU[i];
  61. switch (MU[i + 1]) {
  62. case '?': {
  63. vc[len] = 1;
  64. break;
  65. }
  66. case '*': {
  67. vc[len] = 2;
  68. break;
  69. }
  70. }
  71. }
  72. qr(k);
  73. frog[len + 1][k + 1] = true;
  74. rg int dk = k + 1;
  75. for (rg int i = len; i; --i) {
  76. rg int di = i + 1;
  77. for (rg int j = 1; j <= dk; ++j) {
  78. switch(vc[i]) {
  79. case 0: {
  80. if (frog[di][j + 1]) {
  81. frog[i][j] = true;
  82. pre[i][j] = j + 1;
  83. }
  84. break;
  85. }
  86. case 1: {
  87. if (frog[di][j + 1]) {
  88. frog[i][j] = true;
  89. pre[i][j] = j + 1;
  90. } else if (frog[di][j]) {
  91. frog[i][j] = true;
  92. pre[i][j] = j;
  93. }
  94. break;
  95. }
  96. case 2: {
  97. for (rg int h = j; h <= dk; ++h) if (frog[di][h]) {
  98. frog[i][j] = true;
  99. pre[i][j] = h;
  100. break;
  101. }
  102. break;
  103. }
  104. }
  105. }
  106. }
  107. if (frog[1][1]) print(1, 1);
  108. else puts("Impossible");
  109. return 0;
  110. }
  111. void print(ci cur, ci v) {
  112. if (cur > len) return;
  113. for (rg int i = v; i < pre[cur][v]; ++i) putchar(CU[cur]);
  114. print(cur + 1, pre[cur][v]);
  115. }

【DP】【CF1099C】 Postcard的更多相关文章

  1. T2980 LR棋盘【Dp+空间/时间优化】

    Online Judge:未知 Label:Dp+滚动+前缀和优化 题目描述 有一个长度为1*n的棋盘,有一些棋子在上面,标记为L和R. 每次操作可以把标记为L的棋子,向左移动一格,把标记为R的棋子, ...

  2. 【10.3校内测试【国庆七天乐!】】【DP+组合数学/容斥】【spfa多起点多终点+二进制分类】

    最开始想的暴力DP是把天数作为一个维度所以怎么都没有办法优化,矩阵快速幂也是$O(n^3)$会爆炸. 但是没有想到另一个转移方程:定义$f[i][j]$表示每天都有值的$i$天,共消费出总值$j$的方 ...

  3. 【DP+树状数组】BZOJ1264-[AHOI2006]基因匹配Match

    [题目大意] 给定n个数和两个长度为n*5的序列,两个序列中的数均有1..n组成,且1..n中每个数恰好出现5次,求两个序列的LCS. [思路] 预处理每个数字在a[i]中出现的五个位置.f[i]示以 ...

  4. BZOJ1079 [SCOI2008]着色方案 【dp记忆化搜索】

    题目 有n个木块排成一行,从左到右依次编号为1~n.你有k种颜色的油漆,其中第i种颜色的油漆足够涂ci个木块. 所有油漆刚好足够涂满所有木块,即c1+c2+-+ck=n.相邻两个木块涂相同色显得很难看 ...

  5. 【DP|多重背包可行性】POJ-1014 Dividing

    Dividing Time Limit: 1000MS Memory Limit: 10000K Description Marsha and Bill own a collection of mar ...

  6. COGS 862. 二进制数01串【dp+经典二分+字符串】

    862. 二进制数01串 ★   输入文件:kimbits.in   输出文件:kimbits.out   简单对比 时间限制:1 s   内存限制:128 MB USACO/kimbits(译 by ...

  7. CodeForces - 597C Subsequences 【DP + 树状数组】

    题目链接 http://codeforces.com/problemset/problem/597/C 题意 给出一个n 一个 k 求 n 个数中 长度为k的上升子序列 有多少个 思路 刚开始就是想用 ...

  8. hihocoder1475 数组分拆【DP+前缀和优化】

    思路: DP[ i ] 代表以 i 结尾的方案数. dp[i] += sum[i] - sum[j - 1] != 0 ? dp[j] : 0 ; 对于100%的数据,满足1<=N<=10 ...

  9. SPOJ130 【DP·背包选取特性】

    题意: 给你n个任务,每个任务有一个起始时间,持续时间,一个权值: 问你怎么分配得到最大值 思路: 数据好大..百度了一发意识到自己好菜啊!背包的特性. dp[i]代表前 i 个能构成的最大值. 对于 ...

  10. lightoj1145 【DP优化求方案】

    题意: 有一个k面的骰子,然后问你n个骰子朝上的面数字之和=s的方案: 思路: dp[i][j] 代表 前 i 个骰子组成 j 有多少种方案: 显然 dp[i][j] = dp[i - 1][j - ...

随机推荐

  1. 打包一个传统的ASP.NET web app作为Docker镜像

    (1)针对NerdDinner应用的Dockerfile内容如下 PS E:\DockeronWindows\Chapter02\ch02-nerd-dinner> cat .\Dockerfi ...

  2. Python-opencv摄像头图像捕获

    实例一 (灰色调度) #!/usr/bin/env python # _*_ coding:utf-8 _*_ import cv2 as cv import numpy as np capture ...

  3. #1490 : Tree Restoration-(微软2017在线笔试)

    输入n m km个数,表示每层的节点个数接下来m行是每层的节点,节点顺序是从左往右的k个叶子节点k*k个矩阵,表示叶子节点之间的距离 输出:每个节点的父亲节点编号,root节点是0 题解:1.很明显, ...

  4. ORM PHP 学习记录

    ORM:object relation mapping,即对象关系映射,简单的说就是对象模型和关系模型的一种映射.为什么要有这么一个映射?很简单,因为现在的开发语言基本都是oop的,但是传统的数据库却 ...

  5. Daily Scrum (2015/11/1)

    今天晚上我们照例召开了每周末的小组例会,主要总结本周的工作和讨论下一周的工作. 首先是本周的一些主要工作: 1.进行了代码的修改和完善. 2.开始进行服务器配置和UI. 3.学习借鉴了nutch爬虫的 ...

  6. 20162319 实验四 Android程序设计

    Android Stuidio的安装测试: 完成Hello World, 要求修改res目录中的内容,Hello World后要显示自己的学号 ·实验过程 完成任务一,只需在Android应用程序文件 ...

  7. Alpha版本冲刺(五)

    目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...

  8. iOS开发面试题(中级)

    //想面试的童鞋们来看看自己会多少, 老鸟可以无视直接绕过...1. Object-c的类可以多重继承么?可以实现多个接口么?Category是什么?重写一个类的方式用继承好还是分类好?为什么?与Ex ...

  9. jQ 小球碰撞检测

    <!doctype html> <html> <head> <meta charset="UTF-8"> <title> ...

  10. 在Google Chrome中快速解除网页屏蔽鼠标右键、复制等限制

    第一步,将书签栏设置为显示状态!   第二步,添加新书签——>在标签栏点击右键,选择“添加网页”. 第三步,设置新书签的内容. 1.起名.这个凭个人爱好吧 2.网址栏输入: javascript ...