「Algospot」量化QUANTIZE
一道不难的DP题,主要是为了总结这类最优化题的思路;同时还学到了一个新操作
传送门:$>here<$
题意
给出一个长度为$N$的序列,要求最多使用s个数字进行量化(有损压缩),即代替原数字:使得量化后各个被代替的数与代替的数的差的平方之和最小。
数据范围:$n \leq 100, s \leq 10$
Solution
动态规划的常规思路
容易发现肯定选择数值相近的一些数字用一个数字取替代,所以肯定先排序。
排序完后就是一个简单的dp题了。$dp[i][j]$表示前$i$个数字,使用$j$个数字量化的最小误差。当前决策一定关于第$i$个数字有关,问题在于究竟这一段要多长。在枚举一个k,转移就很明显了:
$dp[i][j]=Min\{dp[k][j-1]+quantize(k+1,i)\}$
究竟用什么来做量化的值
问题转化为了如何求$quantize$函数。就这道题的范围来看,从最小到最大枚举也是没有问题的。但实际上有$O(1)$方法。
设我们选择$m$来量化,也就是说函数$y=\sum\limits_{i=l}^{r}(m-a[i])^2$最小。问题转化为求此函数的最小值。
这是个二次函数,所以展开后直接求导(或直接使用顶点公式),找到顶点的$x$坐标即可。
$y=\sum\limits_{i=l}^{r}(m-a[i])^2=(r-l+1)m^2-2m\sum\limits_{i=l}^{r}a[i]+\sum\limits_{i=l}^{r}a[i]^2$
当$y'=2(r-l+1)m-2\sum\limits_{i=l}^{r}a[i]=0$时
$m=\frac{\sum\limits_{i=l}^{r}a[i]}{r-l+1}$
这就是平均值!由此我们得到结论:当利用平均值来当量化值时,差的平方之和最小。
透过题解看本质
其实对于这类最优化dp问题,可以看做是递归问题。dp的本质是记忆化搜索,只不过可以利用递推来实现。当我搜到这一步时需要枚举来决策当前需要多长的一段来量化,而剩余的则不需要递归,而是直接利用之前做好的最优子结构。这就是dp为什么比dfs快了。其实dp就是暴力,它终究需要考虑所有需要且可能的情况。
my code
具体在实现的时候通过统计前缀和以及平方的前缀和来$O(1)$完成求解。注意把$m$代入求误差时也要利用前缀和。
注意平均值应该四舍五入。
/*By DennyQi 2018*/
#include <cstdio>
#include <queue>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = ;
const int MAXM = ;
const int INF = 0x3f3f3f3f;
inline int Max(const int a, const int b){ return (a > b) ? a : b; }
inline int Min(const int a, const int b){ return (a < b) ? a : b; }
inline int read(){
int x = ; int w = ; register char c = getchar();
for(; c ^ '-' && (c < '' || c > ''); c = getchar());
if(c == '-') w = -, c = getchar();
for(; c >= '' && c <= ''; c = getchar()) x = (x<<) + (x<<) + c - ''; return x * w;
}
int T,N,s;
int a[MAXN],dp[MAXN][],sum[MAXN],ssqr[MAXN];
inline int calc(int l, int r, int m){
int res = ;
res += m*m * (r-l+);
res += ssqr[r] - ssqr[l-];
res -= *m*(sum[r]-sum[l-]);
return res;
}
inline int quantize(int l, int r){
int m = (sum[r]-sum[l-]) / (r-l+);
return Min(calc(l,r,m), calc(l,r,m+));
}
inline int Solve(){
sort(a+,a+N+);
sum[] = ssqr[] = ;
for(int i = ; i <= N; ++i){
sum[i] = sum[i-] + a[i];
ssqr[i] = ssqr[i-] + a[i] * a[i];
}
memset(dp,INF,sizeof(dp));
for(int i = ; i <= s; ++i) dp[][i] = ;
for(int i = ; i <= N; ++i){
for(int j = ; j <= s; ++j){
for(int k = ; k < i; ++k){
dp[i][j] = Min(dp[i][j], dp[k][j-] + quantize(k+,i));
}
}
}
return dp[N][s];
}
int main(){
// freopen(".in","r",stdin);
T = read();
while(T--){
N = read(), s = read();
for(int i = ; i <= N; ++i){
a[i] = read();
}
printf("%d\n", Solve());
}
return ;
}
「Algospot」量化QUANTIZE的更多相关文章
- 「Algospot」津巴布韦ZIMBABWE
同时考验对状压DP和数位DP的理解: 传送门:$>here<$ 题意 给出一个数字$e$,现在对$e$通过$m$进行变换得到$x$:变换的要求是:1.只能改变原数字$e$各个数位的顺序(可 ...
- 「Algospot」龙曲线DRAGON
一道考验思维的好题,顺便总结求第k大问题的常规思路: 传送门:$>here<$ 题意 给出初始串FX,每分形一次所有X替换为X+YF,所有Y替换为FX-Y.问$n$代字符串第$p$位起长度 ...
- 「译」JUnit 5 系列:扩展模型(Extension Model)
原文地址:http://blog.codefx.org/design/architecture/junit-5-extension-model/ 原文日期:11, Apr, 2016 译文首发:Lin ...
- 面试都在问的「微服务」「RPC」「服务治理」「下一代微服务」一文带你彻底搞懂!
❝ 文章每周持续更新,各位的「三连」是对我最大的肯定.可以微信搜索公众号「 后端技术学堂 」第一时间阅读(一般比博客早更新一到两篇) ❞ 单体式应用程序 与微服务相对的另一个概念是传统的「单体式应用程 ...
- 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!
「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...
- 「译」JUnit 5 系列:条件测试
原文地址:http://blog.codefx.org/libraries/junit-5-conditions/ 原文日期:08, May, 2016 译文首发:Linesh 的博客:「译」JUni ...
- JavaScript OOP 之「创建对象」
工厂模式 工厂模式是软件工程领域一种广为人知的设计模式,这种模式抽象了创建具体对象的过程.工厂模式虽然解决了创建多个相似对象的问题,但却没有解决对象识别的问题. function createPers ...
- 「C++」理解智能指针
维基百科上面对于「智能指针」是这样描述的: 智能指针(英语:Smart pointer)是一种抽象的数据类型.在程序设计中,它通常是经由类型模板(class template)来实做,借由模板(tem ...
- 「JavaScript」四种跨域方式详解
超详细并且带 Demo 的 JavaScript 跨域指南来了! 本文基于你了解 JavaScript 的同源策略,并且了解使用跨域跨域的理由. 1. JSONP 首先要介绍的跨域方法必然是 JSON ...
随机推荐
- python3-随机生成10位包含数字和字母的密码
方法一: 知识点:random.sample(sequence, k) 从指定序列中随机获取指定长度的片断 import random,string num=string.ascii_letters+ ...
- 关于C#的new与override
先放出来两个基类和派生类: public class BaseClass { public virtual void Method1(string desc) { Console.WriteLine( ...
- Java 设置PDF文档背景色
一般生成的PDF文档默认的文档底色为白色,我们可以通过一定方法来更改文档的背景色,以达到文档美化以及保护双眼的作用. 以下内容提供了Java编程来设置PDF背景色的方法.包括: 设置纯色背景色 设置图 ...
- cesium 之地图显示坐标、比例尺、海拔高度效果篇(附源码下载)
前言 cesium 官网的api文档介绍地址cesium官网api,里面详细的介绍 cesium 各个类的介绍,还有就是在线例子:cesium 官网在线例子,这个也是学习 cesium 的好素材. 内 ...
- (详细)华为荣耀4X CHE-TL00H的usb调试模式在哪里打开的步骤
每当我们使用PC通过数据线链上安卓手机的时候,如果手机没有开启usb开发者调试模式,PC则没能成功读到我们的手机,有时,我们使用的一些功能较强的工具好比之前我们使用的一个工具引号精灵,老版本就需要打开 ...
- 工具资源系列之给mac装个虚拟机
mac 系统安装虚拟机目前有两种主流软件,一种是 Parallels Desktop ,另一种是 vmware. 本教程选用的是 vmware ,因为我之前 windows 上安装的虚拟机软件就是vm ...
- selenium-测试框架搭建(十三)
思路 分离业务代码和测试数据,提高代码可维护性,实现自动化,减少重复劳动. 一个测试框架大概由配置文件,测试数据,测试用例,相关文件(发送邮件等),测试日志,断言和测试报告等模块组成. 结构 以页面为 ...
- iOS 多线程 NSOperation、NSOperationQueue
1. NSOperation.NSOperationQueue 简介 NSOperation.NSOperationQueue 是苹果提供给我们的一套多线程解决方案.实际上 NSOperation.N ...
- 《Python 数据科学实践指南》读书笔记
文章提纲 全书总评 C01.Python 介绍 Python 版本 Python 解释器 Python 之禅 C02.Python 基础知识 基础知识 流程控制: 函数及异常 函数: 异常 字符串 获 ...
- Tomcat调试404错误
开篇附上我找到的部分解决方法摘自:https://blog.csdn.net/psp0001060/article/details/51879232 如不想跳转查看,链接内容如下: 问题一: ...