UVA 1534 - Taekwondo(dp)

题目链接:1534 - Taekwondo

题意:两组人比赛,一组n1人,一组n2人,选择min(n1,n2)组出来,要求两两人重量差绝对值之和最小。

思路:首先先预处理让n1变成人少的一组,人少的每个人都必须去匹配,dp[i][j] i表示n1组第i个人,j表示第二组多少人没匹配,于是匹配的时候n1组的第i人就和n2组的第i + j的人去匹配,然后进行状态转移

dp[i][j] = {dp[i - 1][k] + fabs(a1[i] - a2[i + j]), (0 <= k <= abs(n1 - n2)},这样时间复杂度要O(n^3),进行优化,dp[i - 1][k]可以在第二城循环的时候顺便维护一个最小值Min,这样复杂度优化到O(n^2)。

代码:

#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <stdlib.h>
#include <math.h>
using namespace std;
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b))
#define INF 0x3f3f3f3f
const int N = 505;
int t, n1, n2, i, j, k;
double a1[N], a2[N], dp[N][N];

void tra() {
	if (n1 > n2) {
		for (int i = 1; i <= n1; i++) {
			double t = a1[i];
			a1[i] = a2[i];
			a2[i] = t;
		}
		int t = n1;
		n1 = n2;
		n2 = t;
	}
	k = n2 - n1;
}

int main() {
	scanf("%d", &t);
	while (t--) {
		double ans = INF;
		scanf("%d%d", &n1, &n2);
		for (i = 1; i <= n1; i++)
			scanf("%lf", &a1[i]);
		for (i = 1; i <= n2; i++)
			scanf("%lf", &a2[i]);
		tra();
		sort(a1 + 1, a1 + n1 + 1);
		sort(a2 + 1, a2 + n2 + 1);
		for (i = 1; i <= n1; i++) {
			double Min = INF;
			for (j = 0; j <= k; j++) {
				if (i + j > n2) break;
				Min = min(Min, dp[i - 1][j]);
				dp[i][j] = INF;
				dp[i][j] = min(dp[i][j], Min + fabs(a1[i] - a2[i + j]));
				if (i == n1)
					ans = min(ans, dp[i][j]);
			}
		}
		printf("%.1lf\n", ans);
	}
	return 0;
}

UVA 1534 - Taekwondo(dp),码迷,mamicode.com

时间: 2024-10-05 22:27:01

UVA 1534 - Taekwondo(dp)的相关文章

uva 1534 - Taekwondo(dp+贪心)

题目连接:uva 1534 - Taekwondo 题目大意:有两组什么东西,题目背景有点忘记了,就是给出两组数,两组个数分别为n,m,要求找出min(n,m)对数,每个数最多最多选一次,使得这min(n,m)对数ai,bi,ai-bi的绝对值之和最小. 解题思路:贪心,将两组数分别排序,然后dp[i][j]表示i对,匹配到j时候的最优解. #include <cstdio> #include <cstring> #include <cmath> #include &l

uva 12723 概率dp

Dudu is a very starving possum. He currently stands in the first shelf of a fridge. This fridge iscomposed of N shelves, and each shelf has a number Qi (1 ≤ i ≤ N) of food. The top shelf, whereDudu is, is identified by the number 1, and the lowest is

uva 11133 - Eigensequence(dp)

题目链接:uva 11133 - Eigensequence 题目大意:给定一个序列a,能够确定一个序列b,要求: 1)b[1]=a[1] 2)a[j?1]<b[j]≤a[j]且b[j]a[j]?a[j?1]为整数,j>1的时候 假设对于每一个ai=bi,则称b序列为Eigensequence序列. 如今给定a1和an,问有多少个Eigensequence序列. 解题思路:dp[i][j]表示第i个数为j的情况有多少种,假设k整除k-j,dp[i+1][k]+=dp[i][j]. #inclu

uva 11367 dijkstra+dp状态压缩

题意:给出n个地点 和 每个地点的油价 ,有 m 条边 , 并给出每条边长度 .1单位汽油可以走1千米  , 油箱的容量为 c , 在初始点 s 时 , 油箱中的油为 0 , 求s 到 t 的最小花费 . 解法: 定义 状态 d[i][j] 表示到达 地点 i 且油箱中有 j 单位油时的最小 花费. 对于状态的转移时 , 有两种方法: 1.把每个点的所有状态都求出 2.不把每个点的状态都求出 , 而是一单位一单位的加油. 对于第一种方法 , 会超时 , 因为每个点的状态太多 , 但是能用的状态就

uva 10593 - Kites(dp)

题目链接:uva 10593 - Kites 题目大意:给出一个n*n的图,表示一张纸板,问有多少种方法做成风筝,风筝必须是正方形或者是菱形,并且不能有洞. 解题思路:分正方形和菱形两种情况讨论: 正方形,dp[i][j]表示以i,j为右下角的正方形 dp[i][j]=min(dp[i?1][j],dp[i][j?1]) 并且如果黄色部分也为'x'的话,dp[i][j]++ 菱形,dp[i][j]表示菱形的正下角 同样地市黄色部分如果为'x'的话,dp[i][j]++ #include <cst

uva 10237 - Bishops(dp)

克里斯·厄姆森 谷歌今天在 Code 大会上发布了新的无人驾驶汽车.该汽车看起来像是有轮子的缆车,它既没有驾驶盘,也没有刹车踏板和加速装置.Re/code 采访了谷歌无人驾驶汽车项目主管克里斯·厄姆森(Chris Urmson),期间谈及该项目革命背后的概念.产品何时上路等问题. 谷歌在过去的 5 年里改装了现成车型去试验无人驾驶技术.除了车顶的旋转激光装置外,它们看上去跟普通车没什么不同.而该公司今天发布的汽车看上去则非常怪异.它们又小又圆,配备各种小型黑色传感器(车顶也有旋转激光装置),用泡

uva 674 (入门DP, 14.07.09)

 Coin Change  Suppose there are 5 types of coins: 50-cent, 25-cent, 10-cent, 5-cent, and 1-cent. We want to make changes with these coins for a given amount of money. For example, if we have 11 cents, then we can make changes with one 10-cent coin an

UVA 10003 区间DP

这个题目蛮有新意的,一度导致我没看透他是区间DP 给一个0-L长度的木板,然后给N个数,表示0-L之间的某个刻度,最后要用刀把每个刻度都切一下 使其断开,然后每次分裂的cost是分裂前的木板的长度.求整个分开之后的最小cost. 当时下意识就想到类似花瓶插花问题,即dp[i][j],表示第i个事物放在第j次动作来的最小代价,但是当我写起来发现很麻烦,我是以刻度点来表示的i,结果发现处理起来相当麻烦,因为实体实际是一块一块的小木板,以点作为转移变量 不仅要加诸多限制,而且加完后发现会互相矛盾,原因

uva 1350 - Pinary(dp+计数)

题目链接:uva 1350 - Pinary 题目大意:给出n,输出第n给Pinary Number,Pinary Number为二进制数,并且没有连续两个1相连. 解题思路:dp[i]表示到第i位有dp[i]种,于是给定n,一层循环判断dp[i]≤n的话,就输出1,并且n减掉dp[i],注意输出0的时候,不能输出前导0. #include <cstdio> #include <cstring> typedef long long ll; const int N = 50; ll