【湖南师范大学2018年大学生程序设计竞赛新生赛 L】【HDOJ2476】【区间DP】
https://www.nowcoder.com/acm/contest/127/L
L 小小粉刷匠
题目描述
输入描述:
对于每一个案例,我们第一行包括两个整数n,k(1<=n<=100,1<=k<=50,k<n),表示墙的长度为n,刷子的长度为k。第二行输入n个整数,表示对于墙的每一段指定的颜色。
输出描述:
输出一个数,表示小名最少刷多少次。
输入例子:
3 3
1 2 1
输出例子:
2
-->
输入
3 3
1 2 1
输出
2
输入
5 4
5 4 3 3 4
输出
3
题意:给一个大小为n的数组SKT和一个大小为n的空数组,一次只能将空数组一个区间(区间大小为(1~k))的值设置为同一个数,问最少操作几次能将空数组改成该数组。
题解:见下面一题的题解。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main() {
int dp[][];
int qwq[];
memset(dp,0x3f3f3f3f,sizeof(dp));
int n, k;
scanf("%d%d",&n,&k);
for (int i = ; i < n; i++) {
scanf("%d", &qwq[i]);
}
for (int i = n - ; i >= ; i--) {
for (int j = i; j < n; j++) {
if (i == j)dp[i][j] = ;
else dp[i][j] = dp[i + ][j]+;
for (int skt = i + ; skt < i + k&&skt<=j; skt++) {
if (qwq[skt] == qwq[i]) {
if (skt == j) {
dp[i][j] = min(dp[i][j], dp[i + ][j]);
}
else dp[i][j] = min(dp[i][j], dp[i + ][skt] + dp[skt + ][j]);
}
}
}
}
cout << dp[][n - ] << endl;
// cout << sizeof(int) * 24300000/1024<<"KB" << endl;
return ;
}
http://acm.hdu.edu.cn/showproblem.php?pid=2476
String painter
Time Limit: 5000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 6211 Accepted Submission(s): 2992
The first line contains string A.
The second line contains string B.
The length of both strings will not be greater than 100.
题意:给出两个串s1和s2,一次只能将一个区间刷一次,问最少几次能让s1=s2
题解:看到区间,又是找最少操作次数,想到区间DP。
首先简化一下问题:假如S1本身是一个空串,则问题等同于上一题,则可以使用dp(i,j)表示涂改 i~j 这个区间所需要的最少次数,在涂改位置i的时候,可以看出来如果S1串已经涂改过的字母中不含有与位置 i 要改变成的字母相同的字母,则有dp(i,j)=dp(i+1,j)+1,如果存在相同字母,则可以在那个位置涂改的时候顺便把位置i涂改,此时也就可以进行更新dp(i,j) = min(dp(i,j), dp(i + 1,k) + dp(k + 1,j));答案就是dp(0,n-1),这里也就是上一题的解法了。
而这题的S1不是空串,这和是空串有什么不一样的呢,S1不是空串,那么就有可能S1(i)==S2(i)那么这个时候不需要涂改,也就是ans(i)=ans(i-1),这也是唯一的区别,否则就使用由空串得到的dp数组进行更新,ans(i)=min(ans(i),ans(j)+dp(j+1,i))(其中0<=j&&j<=i)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main() {
int dp[][];
int ans[];
char s1[], s2[];
while (scanf("%s%s", s1, s2) != EOF) {
int len = strlen(s1);
memset(ans, 0x3f3f3f3f, sizeof(ans));
memset(dp, , sizeof(dp));//dp[i][j]当S1为空串时区间i~j的最小需要改动次数
for (int i = len - ; i >= ; i--) {//倒着来是因为更新的时候使用的dp[i+1][k],需要dp[i+1][k]已经是最优
for (int j = i; j < len; j++) {
if (i == j)
dp[i][j] = ;
else
dp[i][j] = dp[i + ][j] + ;//不考虑是否存在相等的字母时,直接在i的位置上涂改,在原来的次数上+1
for (int k = i + ; k <= j; k++) {
if (s2[i] == s2[k]) {//考虑存在字母已经被涂改成与i位置需要涂改的字母,这里i就可以随着那个k进行涂改
if (k == j) {
dp[i][j] = min(dp[i][j], dp[i + ][j]);
}
else {//之所以使用dp[i+1][k]+dp[k+1][j]而不是直接dp[i+1][j]是因为dp[i+1][k]的涂改可以保证多涂改一个i不影响dp[i+1][k]的最优性,而不能保证dp[i+1][j]的最优性
dp[i][j] = min(dp[i][j], dp[i + ][k] + dp[k + ][j]);
}
}
}
}
}
for (int i = ; i < len; i++) {
ans[i] = dp[][i];
}
if (s1[] == s2[])ans[] = ;
for (int i = ; i < len; i++) {
if (s1[i] == s2[i]) {//二者字母相同时,则不需要涂改
ans[i] = ans[i - ];
}
else {
for (int j = ; j < i; j++) {//二者字母不相同时,和S1是空串的状况一样..所以可以使用dp数组更新
ans[i] = min(ans[i], ans[j] + dp[j + ][i]);
}
}
}
cout << ans[len - ] << endl;
}
return ;
}
【湖南师范大学2018年大学生程序设计竞赛新生赛 L】【HDOJ2476】【区间DP】的更多相关文章
- 湖南师范大学2018年大学生程序设计竞赛新生赛 A 齐神和心美的游戏【hash】
[链接]:A [题意]:给你n个数的序列和k.判断是否可以三个数组成k(同一个数可以拿多次) [分析]:每个数vis记录一下.2层循环.两数之和不超过k以及剩下的数出现在序列中那么ok. [代码]: ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1001 - Buy and Resell 【优先队列维护最小堆+贪心】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6438 Buy and Resell Time Limit: 2000/1000 MS (Java/O ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1010 YJJ's Salesman 【离散化+树状数组维护区间最大值】
题目传送门:http://acm.hdu.edu.cn/showproblem.php?pid=6447 YJJ's Salesman Time Limit: 4000/2000 MS (Java/O ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 1009 - Tree and Permutation 【dfs+树上两点距离和】
Tree and Permutation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- hdu6489 2018 黑龙江省大学生程序设计竞赛j题
Problem Description Kayaking is playing a puzzle game containing n different blocks. He marks the bl ...
- HDU - 6440 Dream 2018中国大学生程序设计竞赛 - 网络选拔赛
给定的\(p\)是素数,要求给定一个加法运算表和乘法运算表,使\((m+n)^p = m^p +n^p(0 \leq m,n < p)\). 因为给定的p是素数,根据费马小定理得 \((m+n) ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 Dream hdu6440 Dream 给出一个(流氓)构造法
http://acm.hdu.edu.cn/showproblem.php?pid=6440 题意:让你重新定义任意一对数的乘法和加法结果(输出乘法口诀表和加法口诀表),使得m^p+n^p==(m+n ...
- hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko's loop
Neko's loop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total S ...
- 2018中国大学生程序设计竞赛 - 网络选拔赛 Solution
A - Buy and Resell 题意:给出n个交易点,每次能够选择买或者卖,求获得最大利润 思路:维护两个优先队列,一个是卖,一个是替换,当价格差相同时,优先替换,因为次数要最少 #includ ...
随机推荐
- linux用户管理 用户和用户组管理
用户组的基本命令 groupadd [选项] [参数] -g 指定新建工作的id -r 创建系统工作组,系统工作组的ID小于500,非系统工作组大于500 -K 覆盖配置文件"/etc/lo ...
- POJ 3436 ACM Computer Factory 最大流,拆点 难度:1
题目 http://poj.org/problem?id=3436 题意 有一条生产线,生产的产品共有p个(p<=10)零件,生产线上共有n台(n<=50)机器,每台机器可以每小时加工Qi ...
- Spring注入,Ioc的具体配置
Spring框架的IOC注入: 一.Java部分代码: Person实体类: package com.ioc; import java.util.List; import java.util.Map; ...
- 【转载】sprintf()函数 和 printf()函数
sprintf()函数 和 printf()函数 参考:C++ 中的sprintf和snprintf 函数的区别 - CSDN博客 http://blog.csdn.net/youbingchen/ ...
- JS时间戳和时间之间转换
一.时间转换时间戳 var date = new Date(); //时间对象 var str = date.getTime(); //转换成时间戳 二.时间戳转换为时间 1.转换成形如 2018 ...
- el-container 实践上的布局问题
当自己利用element-ui上面的例子来实现整体布局的时候, 就是自己分开成单独的vue组件时,发现布局是不对的,效果是这样的: 代码是这样的,代码一模一样,只是拆开了各个组件,如下图: 后来发现是 ...
- thinkphp5.1学习笔记
由于新公司使用的框架是thinkphp5.1,有必要进一步学习,看来我要把php框架使用完全了,之前就用过laravel和CI框架了. 现在打算只是一个学习的记录,结构会比较凌乱,基本我估计只能自己看 ...
- 关于selenium实现滑块验证
关于selenium实现滑块验证 python2.7+selenium2实现淘宝滑块自动认证参考链接:https://blog.csdn.net/ldg513783697/article/detail ...
- 2019-04-03-day025-异常与日志
内容回顾 考试 6个小时 120分 (100+20) 15:00-18:00 笔试 60分 19:00-22:00 上机考试 40分 + 20分 60分及格不算附加题 简答题 读程序 简单编程 编程题 ...
- TestNG参数化测试-数据提供程序 @DataProvider方式
在 testng.xml 中指定参数可能会有如下的不足: 1.如果你压根不用 testng.xml. 2.你需要传递复杂的参数,或者从Java中创建参数(复杂对象,对象从属性文件或者数据库中读取的et ...