ZSTU 4514: yesky wine锦鲤卡 (线性dp)
题目链接
题面:
4514: yesky wine锦鲤卡
Time Limit: 1 Sec Memory Limit: 128 MB
Submit: 28 Solved: 6
Description
懒羊羊的红酒供应系统优化完成了。懒羊羊好开心!他决定给所有ACMer和OIer包括教练一个机会,幸运者可以取得yesky wine锦鲤卡,免费供应一年的yesky wine。要取得锦鲤卡,需要通过一个游戏,谁是第一个取得游戏的胜利者,就可以拿走锦鲤卡。
游戏的目标很简单,用最少的回合完成红酒瓶游戏。
总共有2排,每排放了一些红酒瓶和木牌。每个红酒瓶上写了一个小写字母,每个木牌上写了一个数。
每个游戏者可以对这2排红酒瓶和木牌进行如下操作:
1 放置红酒瓶。游戏者可以找懒羊羊要1个自己想要字母的酒瓶,然后把它放到任意一行的任意位置。
2 换走木牌。游戏者可以从2排里取走一个木牌,并且向懒羊羊要木牌上写得数字一样多的任意字母的酒瓶,然后把刚才换来的酒瓶按照自己想要的顺序放在原来木牌位置。
3 拿走红酒瓶。游戏者可以拿走任意一个红酒瓶,把它扔在懒羊羊边上的垃圾桶里。
哪个游戏者用最少的操作步数完成,并且是第一个完成的,他就可以拿走锦鲤卡。完成的目标是2排只剩红酒瓶,而且红酒瓶上相对应的字母是一样的。
Input
输入2行,每行仅包含小写字母或0到9的数字
第一行长度最小1,最大不超过10000,第二行长度是1到1000之间,每行的数字不超过100个。
Output
输出最少操作次数
Sample Input
【输入样例1】
wine
4
【输入样例2】
wine5ing
4drinking
Sample Output
【输出样例1】
1
【输出样例2】
2
题解:
最终木牌一定会被替换为红酒瓶,且木牌替换的红酒瓶可以任意。
那么我们上来,先将木牌全部替换为 k 个 ? 表示该处可以放置 k 个任意的红酒瓶。其中 k 为木牌上的数字。
那么现在问题变成,我现在有两个字符串,我可以在任意一个串中的任意位置添加一个字符或者删除任意一个字符,问两个串变得一样需要的步数。
这个问题实际上就是求最长公共子序列的长度。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<set>
#define ll long long
#define pr make_pair
#define pb push_back
#define ui unsigned int
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const int mod=1000000007;
const double eps=1e-8;
const double dnf=1e20;
const double pi=acos(-1.0);
const int maxn=20100;
const int maxm=20100;
const int up=100;
const int maxp=1100;
int dp[18010][1810];
char str1[maxn],str2[maxn];
char a[maxn],b[maxn];
int cnta=0,cntb=0;
int main(void)
{scanf("%s%s",str1,str2);int lena=strlen(str1);int ans=0;for(int i=0;i<lena;i++){if(str1[i]>='0'&&str1[i]<='9'){for(int j=1;j<=str1[i]-'0';j++)a[++cnta]='?';ans++;}else a[++cnta]=str1[i];}int lenb=strlen(str2);for(int i=0;i<lenb;i++){if(str2[i]>='0'&&str2[i]<='9'){for(int j=1;j<=str2[i]-'0';j++)b[++cntb]='?';ans++;}else b[++cntb]=str2[i];}for(int i=1;i<=cnta;i++){for(int j=1;j<=cntb;j++){if(a[i]==b[j]||a[i]=='?'||b[j]=='?')dp[i][j]=dp[i-1][j-1]+1;else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);}}printf("%d\n",cnta+cntb-dp[cnta][cntb]*2+ans);return 0;}
当然也可以直接dp求。
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<string>
#include<queue>
#include<bitset>
#include<map>
#include<set>
#define ll long long
#define pr make_pair
#define pb push_back
#define ui unsigned int
#define lc (cnt<<1)
#define rc (cnt<<1|1)
using namespace std;
const int inf=0x3f3f3f3f;
const ll lnf=0x3f3f3f3f3f3f3f3f;
const int mod=1000000007;
const double eps=1e-8;
const double dnf=1e20;
const double pi=acos(-1.0);
const int maxn=20100;
const int maxm=20100;
const int up=100;
const int maxp=1100;
int dp[10810][1810];
char str1[maxn],str2[maxn];
char a[maxn],b[maxn];
int cnta=0,cntb=0;
int main(void)
{scanf("%s%s",str1,str2);int lena=strlen(str1);int ans=0;for(int i=0;i<lena;i++){if(str1[i]>='0'&&str1[i]<='9'){for(int j=1;j<=str1[i]-'0';j++)a[++cnta]='?';ans++;}else a[++cnta]=str1[i];}int lenb=strlen(str2);for(int i=0;i<lenb;i++){if(str2[i]>='0'&&str2[i]<='9'){for(int j=1;j<=str2[i]-'0';j++)b[++cntb]='?';ans++;}else b[++cntb]=str2[i];}for(int i=0;i<=cnta;i++)dp[i][0]=i;for(int i=0;i<=cntb;i++)dp[0][i]=i;for(int i=1;i<=cnta;i++){for(int j=1;j<=cntb;j++){if(a[i]==b[j]||a[i]=='?'||b[j]=='?')dp[i][j]=dp[i-1][j-1];else dp[i][j]=min(dp[i-1][j],dp[i][j-1])+1;}}printf("%d\n",dp[cnta][cntb]+ans);return 0;}
后记:
2019年第十届蓝桥杯C/C++B组决赛的第一个编程题好像就是这个,但是当时不会做,唉。
ZSTU 4514: yesky wine锦鲤卡 (线性dp)相关推荐
- 0x51.动态规划 - 线性DP(习题详解 × 10)
目录 0x51.动态规划 - 线性DP 0x51.1 LIS问题 Problem A. 登山 (最长下降子序列) Problem B. 友好城市(思维) Problem C. 最大上升子序列和 0x5 ...
- UVA11584 划分成回文串 Partitioning by Palindromes(线性DP划分+DP判断回文串)
整理的算法模板合集: ACM模板 依旧是线性DP 我们使用闫氏DP分析法 总体DP转移的时间复杂度为O(n2)O(n^2)O(n2). 但是这里牵扯到判断 i\tt ii 到 j\tt jj 是否为回 ...
- 洛谷P2401 不等数列(线性DP)
本题使用的是线性DP.就是DP数组难以思考,这里我直接给出 dp[i][j]:表示 1 ~ i 这 i 个数 , 其中j 个 " < " 有几种方法 假设我们已经把 n - ...
- CodeForces - 1096D Easy Problem(线性dp)
题目链接:点击查看 题目大意:给出一个字符串,每个字符都有一个权值,现在需要删除权值和最少的字符,满足字符串中不再含有子序列"hard" 题目分析:线性dp,但我不会,看着题解写的 ...
- CodeForces - 456C Boredom(线性dp)
题目链接:点击查看 题目大意:给出一个由n个数字组成的数列,现在给出规则是,每次选择数列中的一种数字 x,选择后的贡献为 x,不过操作后会删除掉所有数值为 x + 1 和 x - 1 的数,现在问如何 ...
- POJ - 1050 To the Max(最大连续子段和,线性dp)
题目链接:点击查看 题目大意:给出一个n*n的矩阵,每个点都有一个权值,现在要从中选取一个子矩阵要求权值和最大,问这个最大权值和是多少 题目分析:因为是要求子矩阵的权值和最大的问题,我们可以直接维护一 ...
- 牛客 - 「火」皇家烈焰(线性dp)
题目链接:点击查看 题目大意:给出一个字符串表示扫雷游戏,其中: 0:这个格子没有烈焰,且其左右两个格子均没有烈焰 1:这个格子没有烈焰,且其左右两个格子中只有一个烈焰 2:这个格子没有烈焰,且其左右 ...
- CH 5102 Mobile Service(线性DP)
CH 5102 Mobile Service \(solution:\) 这道题很容易想到DP,因为题目里已经说了要按顺序完成这些请求.所以我们可以线性DP,但是这一题的状态不是很好设,因为数据范围有 ...
- 动态规划 —— 线性 DP
[概述] 线性动态规划,是较常见的一类动态规划问题,其是在线性结构上进行状态转移,这类问题不像背包问题.区间DP等有固定的模板. 线性动态规划的目标函数为特定变量的线性函数,约束是这些变量的线性不等式 ...
最新文章
- 常用memcached命令详解
- 图像处理池化层pooling和卷积核
- 源码阅读心得11-13
- Mongodb部署及使用
- 156. Leetcode 53. 最大子数组和 (贪心算法-进阶题目)
- python爬虫源码附注解_Python小白写的三个入门级的爬虫(附代码和注释)
- lucene api
- 接口可以继承抽象类吗_Python接口类的多继承以及抽象类的单继承
- Android Studio AVD中文输入法安装
- 【OpenCV学习笔记】【函数学习】十九(感兴趣区域)
- Ubuntu下mysql可视化_ubuntu上mysql有可视化界面吗 ubuntu mysql 图形界面
- 晋南讲堂之持久层框架ORM简介
- 对幅度谱和相位谱的理解
- 【考研数学一】微分方程专讲(初步)
- alertmanager配置详解
- python 高德/百度/腾讯/谷歌API 与WGS84坐标互转(BD09/GCJ02/WGS84)
- 计算机网络atm功能,自考计算机网络实用技术考核知识点之ATM原理
- 对有序表的查找(快步搜索算法)
- undefined control sequence_control两个超级实用的短语解析
- 编写Java程序,从键盘输入一个正整数n(n≥2),随机生成一个n阶方阵,每个元素均为整数,其取值范围为[100,999]。然后输出该方阵元素中的最大值和最小值。