HihoCoder1532 : 最美和弦(DP简单优化)
描述
某个夜晚,Bob将他弹奏的钢琴曲录下来发给Jack,Jack感动之余决定用吉他为他伴奏。
我们可以用一个整数表示一个音符的音高,并可认为Bob弹奏的曲子是由3N个整数构成的一个序列。其中每个整数的取值范围是[-200, 200]。
Jack共弹奏 N 个和弦,每个和弦由三个音符组成。Jack可以自行决定和弦的第一个音符,其后的两个音符由第一个音符与和弦种类所决定。Jack共弹奏两种和弦:大三和弦与小三和弦。假设Jack决定某个和弦的第一个音符是 x,那么对于大三和弦,余下两个音符依序是 x+4和 x+7;对于小三和弦,余下两个音符依序是x+3和x+7。两个和弦相同,当且仅当其对应位置的三个音符都相同。其中每个和弦的第一个音符x的取值范围也是[-200, 200]。
Jack很懒,一旦决定弹奏某个和弦后,便不愿意更换和弦。即如果他开始弹奏1,5,8这个和弦,他将不停重复1,5,8,1,5,8,1,5,8……Bob觉得这样过于单调,于是Jack妥协:他表示愿意更换和弦,但最多更换K次。最开始选择和弦不计在更换次数内。
我们用不和谐值衡量乐曲与伴奏之间的契合程度。记某时刻Bob弹奏音符的音高为a,Jack弹奏音符的音高为b,则该点的不和谐值为|a-b|。整首乐曲的不和谐值等于这3N个不和谐值之和。
Jack希望选取最美的一组和弦,使得整首乐曲的不和谐值达到最小。你需要输出这个最小值。
输入
第一行两个正整数 N (≤1000), K (≤20).
第二行3N个整数(取值范围[-200, 200])为Bob的曲谱。
输出
一个整数,为乐曲最小不和谐值。
样例输入
- 3 1
- -1 3 6 4 7 11 21 26 28
样例输出
- 15
思路:dp[N][X][K][1]表示第N个和弦,用了K次机会,最后一次用的是3还是4。
每一次,都可以选择换或者不换,换的时候前面一次的X与现在的X不同,因此需要for循环枚举X,但是这样复杂度太高。需要记录前面用那个X最小,及代码里的Min。
那么最近经常做到记录前面最优的DP,这里有两道区间题,需要前缀和优化DP:http://www.cnblogs.com/hua-dong/p/8452988.html
- #include<cmath>
- #include<cstring>
- #include<cstdio>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- using namespace std;
- const int inf=;
- int dp[][][][],a[];
- int Min[][][];
- int abs(int x){ if(x<) return -x; return x; }
- int main()
- {
- int N,K,i,j,k,ans=inf;
- scanf("%d%d",&N,&K);
- for(i=;i<=N;i++)
- for(j=;j<=K;j++)
- Min[i][j][]=Min[i][j][]=inf;
- for(i=;i<=*N;i++) scanf("%d",&a[i]);
- for(i=;i<=N;i++){
- for(j=-;j<=;j++){ //K=0,显然不能换
- dp[i][j+][][]=dp[i-][j+][][]+abs(a[*(i-)+]-j)+abs(a[*(i-)+]-j-)+abs(a[*(i-)+]-j-);
- Min[i][][]=min(Min[i][][],dp[i][j+][][]);
- dp[i][j+][][]=dp[i-][j+][][]+abs(a[*i-]-j)+abs(a[*i-]-j-)+abs(a[*i]-j-);
- Min[i][][]=min(Min[i][][],dp[i][j+][][]);
- }
- for(k=;k<=K;k++)
- for(j=-;j<=;j++){//K>0,当前j可能是换后的,可能没有换。
- dp[i][j+][k][]=min(dp[i-][j+][k][],Min[i-][k-][])+abs(a[*i-]-j)+abs(a[*i-]-j-)+abs(a[*i]-j-);
- dp[i][j+][k][]=min(dp[i][j+][k][],Min[i-][k-][]+abs(a[*i-]-j)+abs(a[*i-]-j-)+abs(a[*i]-j-));
- Min[i][k][]=min(Min[i][k][],dp[i][j+][k][]);
- dp[i][j+][k][]=min(dp[i-][j+][k][],Min[i-][k-][])+abs(a[*i-]-j)+abs(a[*i-]-j-)+abs(a[*i]-j-);
- dp[i][j+][k][]=min(dp[i][j+][k][],Min[i-][k-][]+abs(a[*i-]-j)+abs(a[*i-]-j-)+abs(a[*i]-j-));
- Min[i][k][]=min(Min[i][k][],dp[i][j+][k][]);
- }
- }
- for(k=;k<=K;k++){
- ans=min(ans,Min[N][k][]);
- ans=min(ans,Min[N][k][]);
- }
- printf("%d\n",ans);
- return ;
- }
HihoCoder1532 : 最美和弦(DP简单优化)的更多相关文章
- 「模拟赛20181025」御风剑术 博弈论+DP简单优化
题目描述 Yasuo 和Riven对一排\(n\)个假人开始练习.斩杀第\(i\)个假人会得到\(c_i\)个精粹.双方轮流出招,他们在练习中互相学习,所以他们的剑术越来越强.基于对方上一次斩杀的假人 ...
- 【BZOJ-3437】小P的牧场 DP + 斜率优化
3437: 小P的牧场 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 705 Solved: 404[Submit][Status][Discuss ...
- HDU3480_区间DP平行四边形优化
HDU3480_区间DP平行四边形优化 做到现在能一眼看出来是区间DP的问题了 也能够知道dp[i][j]表示前 i 个节点被分为 j 个区间所取得的最优值的情况 cost[i][j]表示从i ...
- 动态规划DP的优化
写一写要讲什么免得忘记了.DP的优化. 大概围绕着"是什么","有什么用","怎么用"三个方面讲. 主要是<算法竞赛入门经典>里 ...
- 「学习笔记」wqs二分/dp凸优化
[学习笔记]wqs二分/DP凸优化 从一个经典问题谈起: 有一个长度为 \(n\) 的序列 \(a\),要求找出恰好 \(k\) 个不相交的连续子序列,使得这 \(k\) 个序列的和最大 \(1 \l ...
- 【BZOJ】1096: [ZJOI2007]仓库建设(dp+斜率优化)
http://www.lydsy.com/JudgeOnline/problem.php?id=1096 首先得到dp方程(我竟然自己都每推出了QAQ)$$d[i]=min\{d[j]+cost(j+ ...
- 数位dp 简单入门
推荐博客 推荐博客 数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数.所谓数位dp,字面意思就是在数位上进行dp咯.数位还算是比较好听的名字,数位的含义:一个数有 ...
- 一次千万级别的SQL查询简单优化体验
背景:从两张有关联的表查询数据,A表数据量1400万,B表数据量8000万.A与B通过ID逻辑关联,没有实际的外键.B表是后来扩展出来的. 问题:根据某个ID查询时超时,运行时跑不出结果. 原因:使用 ...
- 【BZOJ-4518】征途 DP + 斜率优化
4518: [Sdoi2016]征途 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 230 Solved: 156[Submit][Status][ ...
随机推荐
- windows symbol server调试
linux下gdb强大的调试功能让人印象深刻,一直以为windows下调试可执行程序非常让人头痛.经一些高人指点后知道原来windows下还有symbol server这种调试工具 参见下面两个文档 ...
- IntelliJ IDEA常用的快捷键(代码提示/注释代码/加入类注释和方法注释Javadoc)
说明:IDEA的快捷键非常的多,但是下面这几种快捷键应该是最常用到的. 一.代码提示: [Ctrl]+[空格] 这个通常会与输入法开关冲突,解决方法是屏蔽输入法开关. 二.注释: 1.单行:[Ctrl ...
- Java日志框架-Spring中使用Logback(Spring/Spring MVC)
继上一篇文章http://www.cnblogs.com/EasonJim/p/7800880.html中所集成的是基于Java的普通项目,如果要在Spring和Spring MVC上集成,需要做如下 ...
- IOS --关于粘贴板 ,剪切板 ,UILabel的复制
在iOS中下面三个控件,自身就有复制-粘贴的功能: 1.UITextView 2.UITextField 3.UIWebView UIKit framework提供了几个类和协议方便我们在自己的应用程 ...
- lib无法访问另外lib中的头文件
工程中app已经有设置User Header Search Paths来包含了需要的头文件,但是个别的lib依然找不到头文件.解决方法: 选择这个lib,在Build Settings中查找选项Use ...
- Liunx常用命令(备用)
常用指令 ls 显示文件或目录 -l 列出文件详细信息l(list) -a 列出当前目录下所有文件及目录,包括隐藏的a(all) mkdir ...
- JAVA_MyEclipse常见配置NETGEAR路由器如何设置
1 把宽带网线接到路由器的Internet口,然后用一个网线连接PC和路由器的任意端口(1,2,3,4一般四个),如下图所示 2 在浏览器地址栏中输入下面的网址,中途会弹出对话框询问账号密码,默认的账 ...
- Linux下的ELF可执行文件的格式解析 (转)
LInux命令只是和Kernel一起被编译进操作系统的存在于FS的ELF格式二进制文件,或者权限足够的脚本,或者一个软链 ELF(Executable and Linking Format)是一种对象 ...
- 为什么说JAVA中要慎重使用继承 C# 语言历史版本特性(C# 1.0到C# 8.0汇总) SQL Server事务 事务日志 SQL Server 锁详解 软件架构之 23种设计模式 Oracle与Sqlserver:Order by NULL值介绍 asp.net MVC漏油配置总结
为什么说JAVA中要慎重使用继承 这篇文章的主题并非鼓励不使用继承,而是仅从使用继承带来的问题出发,讨论继承机制不太好的地方,从而在使用时慎重选择,避开可能遇到的坑. JAVA中使用到继承就会有两 ...
- hiberinate二级缓存
hibernate.cfg.xml配置 <!-- 二级缓存类型 --> <property name="hibernate.cache.region.factory_cla ...