题目

参考
把一串包含n个数字的序列,分成若干个cluster,不改变数字在原来序列中的顺序(即相当于在原序列中插入隔板来分割),使得每个cluster满足如下要求:

  • 至少包含p个元素
  • 顺序为原list中的顺序
  • 所有cluster的均方误差之和最小

均方误差的计算方法:

double squareDiviation(const vector<int>& s) {double sum = 0, res = 0;for_each(s.begin(), s.end(), [&sum](int val) { sum += val; });sum /= s.size();for_each(s.begin(), s.end(), [&res, sum](int val) { res += pow(val - sum, 2); });return res;
}

使用动态规划的准备工作:

  • 计算所有可能的cluster的累加和
  • 计算每个可能的cluster的均方误差

排列组合的思想,n个数字的序列,可以分为 n(n+1)/2 种不同的cluster,用矩阵保存相应的累加和,例如:clusterSum[i][j]表示,第i个数一直加到j个数的累加和;clusterSquareDiv[i][j]表示,第i个数到第j个数这个cluster的均方误差。

定义状态转移方程

dp是一个大小为(n+1)的一维数组,dp[i]表示到第i个数(不包括i)为止,左边的cluster最小的均方误差和。
相当于我们已经知道了对于 j个数字的序列(以及小于j个数字的序列)的最优解,再增加一个数字后,如何划分cluster来达到最优解。
方法(类似滑动窗口):固定新cluster的右边界为这个新增的数字,移动cluster的左边界来查找能使得 (新cluster的均方误差) + (他左边的所有cluster的均方误差之和)最小 的一个界限。

初始条件
  • dp[0] = 0
  • dp[k] = MAX_VALUE, (k > 0 && k <= n)
转移方程
dp[j] = min({dp[k] + clusterSquareDiv[k][j-1] | 0 <= k < j - p })

代码实现

#include<iostream>
#include<vector>
#include <cmath>
#include <cstdio>
#include <algorithm>using namespace std;/*** 每一个小set要同时满足三个条件:* 1、至少包含p个元素* 2、包含的数要在原list中连续* 3、方差要尽量小* @return*/
int main() {int T;cin >> T;for (int i = 0; i < T; ++i) {int n, p;cin >> n >> p; // 每个小集合中至少p个元素vector<int> arr(n);vector<vector<int>> clusterSum(n , vector<int>(n));vector<vector<double>> clusterSquareDiv(n , vector<double>(n));for (auto& a : arr) {cin >> a;}// 计算每个小区间的和for (int j = 0; j < n; ++j) {for (int k = j; k < n; ++k) {if (j == k) {clusterSum[j][k] = arr[k];} else {clusterSum[j][k] = clusterSum[j][k - 1] + arr[k];}}}for (int j = 0; j < n; ++j) {for (int k = j + p - 1; k < n; ++k) {double tempBlockSum = (double)clusterSum[j][k] / (k - j + 1);for (int l = j; l <= k; ++l) {// 计算每个小区间的均方误差clusterSquareDiv[j][k] += pow(arr[l] - tempBlockSum, 2);}}}vector<double> dp(n+1, 1e15); // 注意!这个数要选择的足够大dp[0] = 0; // dp[i]表示到第i个数(不包括i)为止,左边的cluster最小的均方误差和for (int j = p; j <= n; ++j) { // cluster右边界for (int k = j - p; k >= 0; k--) {dp[j] = min(dp[j], dp[k] + clusterSquareDiv[k][j - 1]);}}if (i != 0) {cout << endl;}cout << "Case " << i+1 << ":\n";printf("%.2f\n", dp[n]);}return 0;
}

WOJ 1023 Division题解相关推荐

  1. [bzoj1023][SHOI2008]cactus仙人掌图【仙人掌】

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1023 [题解] 仙人掌入门题,拿圆方树练练手. 圆方树就是把一个环建一个新方点,然后向 ...

  2. ZZULIOJ Python题解1023: 大小写转换

    ZZULIOJ题解 1023: 大小写转换 题目描述 输入一个字母,若是小写字母,则变为大写输出,否则,原样输出. 输入 输入为一个字符. 输出 按题目要求输出一个字符,单独占一行. 样例输入 a 样 ...

  3. PAT甲级1023 Have Fun with Numbers:[C++题解]高精度加法和两个vector大小比较

    文章目录 题目分析 题目链接 题目分析 使用高精度加法高精度加法板子求 这个数的两倍,存在一个vector中. 所谓高精度就是使用string来存大的数,然后模拟列竖式加法,结果一位一位压入数组vec ...

  4. 浙大 pat 1023题解

    1023. Have Fun with Numbers (20) 时间限制 400 ms 内存限制 32000 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue ...

  5. Woj 简易题解 Volume #2

    *1101 数据范围太扯淡了..如果不考虑范围的话可以这样想,从一个点到另外一个点他们的哈密顿距离为他们的最短距离,那么这个距离的步数就是我需要的最少步数,假设从一个点到另外一个点要走m步,那么首先从 ...

  6. CodeChef Starters 26 Division 3 (Rated)----STNGAME(中文题解)

    描述: Contest Page | CodeChef 上面是原题目的地址,简要概括一下意思:Alice和Bob在玩一个填字符串的游戏,一开始Alice有n个字符,Bob也有n个字符.他们需要用这些字 ...

  7. 2020ICPC·小米 网络选拔赛第一场 全部题解

    整理的算法模板合集: ACM模板 目录 题目传送门 题目总体情况 A.Intelligent Warehouse B.Intelligent Robot C.Smart Browser D.Route ...

  8. Codeforces 1110 简要题解

    文章目录 A题 B题 C题 D题 E题 F题 G题 传送门 众所周知ldxoildxoildxoi这种菜鸡选手是不会写HHH题的,因此该篇博客只有AAA题至GGG题的题解,实在抱歉. A题 传送门 题 ...

  9. uva 725 Division(暴力模拟)

    Division 紫书入门级别的暴力,可我还是写了好长时间 = = [题目链接]uva 725 [题目类型]化简暴力 &题解: 首先要看懂题意,他的意思也就是0~9都只出现一遍,在这2个5位数 ...

最新文章

  1. 计算机组成原理考研重点
  2. 初始化栈、入栈、出栈、栈空、数制转换函数和主函数,实现1348转换成8进制的功能。
  3. c c++常用算法手册(第3版_嵌入式软件开发必看书籍推荐(C/C++/linux/软件)
  4. java 数据聚合_Java数据聚合问题请教?
  5. 图片(img标签)的onerror事件,你有用过嘛?
  6. 博客入驻阿里“云栖社区”
  7. DL之pix2pix:基于TF利用pix2pix模型对food_resized数据集实现Auto Color自动上色技术—训练测试过程全记录
  8. NLP事件抽取综述(上中下):中文事件抽取、开放域事件抽取、事件数据生成、跨语言事件抽取、小样本事件抽取、零样本事件抽取等类型
  9. 最大值_285期 博最大值2路,已经箭在弦上!
  10. 分页池内存持续增长_鸿蒙内核源码分析(从进程/线程视角看内存)
  11. python eval 字符串替换_Python中eval妙用,字符串转字典和列表
  12. ORACLE中BFILE字段的使用研究
  13. 福州:物联网产业加速集聚 每年安排不低于1000万元专项资金
  14. OpenCV 填充多边形 fillConvexPoly 和 fillPoly
  15. 漂亮的抽奖C#源代码
  16. Maven-Eclipse使用maven创建HelloWorld Java项目
  17. python Socket 客户端
  18. Idea的JShell Console
  19. steamcommunity本地反代443端口/80端口被占用解决办法
  20. 【MySQL】Mcafee审计插件

热门文章

  1. php mysql写入数据不成功,向MYSQL中安插数据不成功
  2. Python 逗号连接列表内容
  3. 飞思卡尔MC9S12X:CAN接收配置
  4. 用Three.js做一个简单的3D场景
  5. ubuntu 安装 confluence
  6. CAD-Cass小结(7)——由高程点生成剖面图(含批量修改高程值)
  7. 谁是卧底在线游戏实战开发thinkphp5+socketio+vue全家桶
  8. 数据分析用Python的Pandas模块读写Excel数据及一些实用的变换、排序、筛选、清洗、列拆分、表合并及相关的坑
  9. 公式编写1000问36-37
  10. Ubuntu下aMule设置