HDU 3392 Pie(DP)
题意:有一些男生女生,男生女生数量差不超过100 ,男生女生两两配对。要求求出一种配对方法,使每一对的高度差的和最小。
思路:(我是真的笨笨笨!!)设人少的一组人数为n,b[],人多的一组人数为m,g[](b[],g[]先排好序),用dp[i][j]表示n中的前i个人与m中的前j个人配对所得到的最小值。
对于每个i,j的范围是(i~i+m-n)

这样j的范围是i~m-n+i,对于dp数组而言,第二维数组要开到m,由于数组过大,而我们又知道,m-n<=100,所以用j表示j-i,j的范围就变成了(0~m-n),也就是(0~100),这种情况下dp[i][j]表示b中前i个人和g中前i+j个人的最小值。
对于每一个dp[i][j]它的可能就是选第i+j个,不选第i+j个数。
如果不选的话,那么dp[i][j]就等于dp[i][j-1],如果选了呢,就是dp[i-1][j]+|b[i]-g[i+j]|
状态转移方程:dp[i][j]=min(dp[i][j-1], dp[i-1][j] + |b[i]-g[i+j]|)
AC代码:
/** hdu 3392 */ #include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std; const int N = 10005;
double a[N], b[N];
double dp[N][110]; double getdp(int m, int n, double *g, double *b)
//m,g为人数多的一组,n,b为人少的一组
{
for (int i = 1; i <= n; ++i) {
dp[i][0] = dp[i - 1][0] + fabs(b[i] - g[i]);//对于dp[...][0],即两组个数相等,没有选择~
for (int j = 1; j <= m - n; ++j) {
dp[i][j] = min(dp[i - 1][j] + fabs(b[i] - g[i + j]), dp[i][j - 1]);
}
}
return dp[n][m - n];
} int main()
{
//freopen("in.txt", "r", stdin);
int boys, girls;
while (scanf("%d%d", &boys, &girls) != EOF && (boys || girls)) {
for (int i = 1; i <= boys; i++) {
scanf("%lf", &a[i]);
}
for (int i = 1; i <= girls; i++) {
scanf("%lf", &b[i]);
}
sort(a + 1, a + 1 + boys);
sort(b + 1, b + 1 + girls);
double ans;
if (boys < girls)
ans = getdp(girls, boys, b, a);
else
ans = getdp(boys, girls, a, b);
printf("%f\n", ans);
}
return 0;
}
但是看了别人的博客,可以用到滚动数组【啊喂!!我就是为了学一下滚动数组才搜到这道题的,结果根本不用啊!】。
滚动数组很神奇啊,因为对于每一个dp[i],求它的过程只与dp[i-1]有关,所以开成2个就够了。既dp[2][...]
代码
/** hdu 3392 */ const int N = 10005;
double a[N], b[N];
double dp[2][110]; double getdp(int m, int n, double *g, double *b)
//m,g为人数多的一组,n,b为人少的一组
{
memset(dp, 0, sizeof(dp));
for (int i = 1; i <= n; ++i) {
dp[i % 2][0] = dp[(i - 1) % 2][0] + fabs(b[i] - g[i]);
for (int j = 1; j <= m - n; ++j) {
dp[i % 2][j] = min(dp[(i - 1) % 2][j] + fabs(b[i] - g[i + j]), dp[i % 2][j - 1]);
}
}
return dp[n % 2][m - n];
}
改了之后注意加一句memset(dp, 0, sizeof(dp));
因为窝之前的dp[0][..]是没有用到的,一直是0……所以不用
对于这种通过%N...来节省数组空间的方法窝觉得真是太神奇了orz……
继续努力~
HDU 3392 Pie(DP)的更多相关文章
- hdu 3392(滚动数组优化dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3392 Pie Time Limit: 6000/3000 MS (Java/Others) Me ...
- hdu 4123 树形DP+RMQ
http://acm.hdu.edu.cn/showproblem.php? pid=4123 Problem Description Bob wants to hold a race to enco ...
- hdu 4507 数位dp(求和,求平方和)
http://acm.hdu.edu.cn/showproblem.php?pid=4507 Problem Description 单身! 依旧单身! 吉哥依旧单身! DS级码农吉哥依旧单身! 所以 ...
- hdu 3709 数字dp(小思)
http://acm.hdu.edu.cn/showproblem.php?pid=3709 Problem Description A balanced number is a non-negati ...
- hdu 4352 数位dp + 状态压缩
XHXJ's LIS Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- hdu 4283 区间dp
You Are the One Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...
- HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化
HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...
- HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化)
HDOJ(HDU).2844 Coins (DP 多重背包+二进制优化) 题意分析 先把每种硬币按照二进制拆分好,然后做01背包即可.需要注意的是本题只需要求解可以凑出几种金钱的价格,而不需要输出种数 ...
- HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化)
HDOJ(HDU).1059 Dividing(DP 多重背包+二进制优化) 题意分析 给出一系列的石头的数量,然后问石头能否被平分成为价值相等的2份.首先可以确定的是如果石头的价值总和为奇数的话,那 ...
随机推荐
- 获取iOS设备型号的方法总结
三种常用的办法获取iOS设备的型号: 1. [UIDevice currentDevice].model (推荐): 2. uname(struct utsname *name) ,使用此函数需要#i ...
- 微软Hololens学院教程-Hologram 210 Gaze(凝视)【微软教程已经更新,本文是老版本】
这是老版本的教程,为了不耽误大家的时间,请直接看原文,本文仅供参考哦!原文链接:https://developer.microsoft.com/EN-US/WINDOWS/HOLOGRAPHIC/ho ...
- C++ 数据类型及相关问题 及输出精度控制
1.有哪些数据类型? 2.数据类型在不同的编译器会有不同的位宽,如何得知? 使用如下命令: cout<<sizeof(int)<<endl; cout<<sizeo ...
- 解决iphone safari上的圆角问题
-webkit-appearance : none ; /*解决iphone safari上的圆角问题*/
- Linux巡检
# uname -a # 查看内核/操作系统/CPU信息 # head -n 1 /etc/issue # 查看操作系统版本 # cat /proc/cpuinfo # 查看CPU信息 # hostn ...
- POJ 1151 Atlantis(离散化)
点我看题目 题意 : 就是给你n个矩形的最左下角和最右上角的点的坐标,然后将这n个矩形的面积求出来. 思路 : 离散化求矩形面积并.离散化具体介绍.将横纵坐标离散开来分别存,然后排序,也可以按照黑书上 ...
- 【转】DCX (数独-八皇后问题)
还没学会,先转了再说.. 出处:http://grenet.cnblogs.com/ 跳跃的舞者,舞蹈链(Dancing Links)算法--求解精确覆盖问题 精确覆盖问题的定义:给定一个由0-1 ...
- [OJ] Single Number II
LintCode 83. Single Number II (Medium) LeetCode 137. Single Number II (Medium) 以下算法的复杂度都是: 时间复杂度: O( ...
- Linux Kernel ‘drivers/staging/wlags49_h2/wl_priv.c’本地缓冲区溢出漏洞
漏洞名称: Linux Kernel ‘drivers/staging/wlags49_h2/wl_priv.c’本地缓冲区溢出漏洞 CNNVD编号: CNNVD-201311-068 发布时间: 2 ...
- c程序设计语言_习题1-19_编写函数reverse(s)将字符串s中字符顺序颠倒过来。
Write a function reverse(s) that reverses the character string s . Use it to write a program that re ...