HIT2244 Get the Colors(dp)

题目链接:

  http://acm.hit.edu.cn/hoj/problem/view?id=2244

题目描述:

Get the Colors

Submitted : 579, Accepted : 111

This problem arises from a research on the newest Web Data Search & Mining technology.

There are several points on the x-axis, each with a color and a unique x-coordinate.

Your task is to calculate the minumum interval on the x-axis that contains all the colors.

Input

This problem has multiple test cases. Each test case begins with an integer N that specifies the number of points. N lines follow, each with two integers Xi and Ci, specifying point i‘s x-coordinate and color. 1 ≤ N ≤ 10000, 1 ≤ Ci ≤ 1000. Xi will fit in signed 32-bit integer.

Output

For each test case, output a single integer, which is the length of the minimum interval that contains all the colors.

Sample Input

6
-5 3
-3 1
0 2
1 3
5 2
10 1

Sample Output

4

题目大意:

  给x轴上点的坐标与颜色,求出包含全部颜色的点的最小区间长度

思路:

  先算出共有多少种颜色(cnt种),然后预处理next数组,计算出每一个点相同颜色的下一个位置是多少

  然后从头开始扫,把位置坐标插入优先队列中(保证队列中只有cnt个点,且他们颜色不同)每次pop出坐标最小的点,将next点push入队

  这样每次算队列中最大坐标与最小坐标之差

  最小的即为答案

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <queue>
 6 using namespace std;
 7
 8 typedef long long LL;
 9
10 const int N = 10010;
11 const int M = 1010;
12 const LL INF = 1e15;
13
14 struct Node {
15     LL x;    //坐标
16     int c;    //颜色
17     Node(LL x = -1, int c = 0) :x(x), c(c) {}
18     const bool operator < (const Node& A) const {
19         return x < A.x;
20     }
21 }no[N];
22
23 struct State {
24     LL p;    //坐标
25     int x;    //数组下标
26     State(LL p = 0, int x = 0) :p(p), x(x) {}
27     const bool operator < (const State& A) const {
28         return p > A.p;
29     }
30 };
31
32 int n, cnt, ne[N], po[M];
33 bool vis[M];
34
35 int main() {
36     while (cin >> n) {
37         cnt = 0;
38         memset(vis, 0, sizeof(vis));
39         for (int i = 0; i < n; ++i) {
40             scanf("%lld%d", &no[i].x, &no[i].c);
41             if (!vis[no[i].c])vis[no[i].c] = true, ++cnt;    //记录颜色数目
42         }
43         sort(no, no + n);    //按坐标排序
44         int tmp = 0, t = 0;
45         LL best = 0, ans = INF;
46         memset(vis, 0, sizeof(vis));
47         memset(po, 0, sizeof(po));
48         while (t < n) {
49             if (!vis[no[t].c])vis[no[t].c] = true, ++tmp;
50             po[no[t].c] = t;
51             if (tmp >= cnt)break;
52             ++t;
53         }    //t为第一个全部颜色都包含的位置
54         priority_queue<State> que;
55         for (int i = 0; i < M; ++i)if (vis[i]) {
56             que.push(State(no[po[i]].x, po[i]));
57             best = max(best, no[po[i]].x);    //队列中坐标最大值
58         }
59         bool hasnext[N] = { 0 };
60         for (int i = t + 1; i < n; ++i) {    //预处理next数组,hasnext记录是否为尾
61             hasnext[po[no[i].c]] = true;
62             ne[po[no[i].c]] = i;
63             po[no[i].c] = i;
64         }
65         while (!que.empty()) {
66             State tmp = que.top();
67             que.pop();
68             ans = min(best - tmp.p, ans);    //记录区间长
69             if (!hasnext[tmp.x])break;
70             tmp = State(no[ne[tmp.x]].x, ne[tmp.x]);
71             best = max(best, tmp.p);    //维护队中坐标最大值
72             que.push(tmp);
73         }
74         printf("%lld\n", ans);
75     }
76 }
时间: 2024-11-08 21:22:06

HIT2244 Get the Colors(dp)的相关文章

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

Ural 1353 Milliard Vasya&#39;s Function(DP)

题目地址:Ural 1353 定义dp[i][j],表示当前位数为i位时,各位数和为j的个数. 对于第i位数来说,总可以看成在前i-1位后面加上一个0~9,所以状态转移方程就很容易出来了: dp[i][j]=dp[i][j]+dp[i][j-1]+dp[i][j-2]+.......+dp[i][j-9]: 最后统计即可. 代码如下: #include <iostream> #include <cstdio> #include <string> #include <

HDU 4908 (杭电 BC #3 1002题)BestCoder Sequence(DP)

题目地址:HDU 4908 这个题是从m开始,分别往前DP和往后DP,如果比m大,就比前面+1,反之-1.这样的话,为0的点就可以与m这个数匹配成一个子串,然后左边和右边的相反数的也可以互相匹配成一个子串,然后互相的乘积最后再加上就行了.因为加入最终两边的互相匹配了,那就说明左右两边一定是偶数个,加上m就一定是奇数个,这奇数个的问题就不用担心了. 代码如下: #include <iostream> #include <stdio.h> #include <string.h&g

Sicily 1146:Lenny&#39;s Lucky Lotto(dp)

题意:给出N,M,问有多少个长度为N的整数序列,满足所有数都在[1,M]内,并且每一个数至少是前一个数的两倍.例如给出N=4, M=10, 则有4个长度为4的整数序列满足条件: [1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 4, 10], [1, 2, 5, 10] 分析:可用动态规划解题,假设dp[i][j],代表满足以整数i为尾数,长度为j的序列的个数(其中每一个数至少是前一个数的两倍).那么对于整数i,dp[i][j] 等于所有dp[k][j-1]的和,其中k满足:

UVA542 - France &#39;98(dp)

UVA542 - France '98(dp) 题目链接 题目大意:之前题目意思还以为看懂了,其实没看明白,它已经把各个选手分在各自所在的区域里面,这就意味着第一次的PK的分组已经确定,而且冠军必须是从两个左右分区出来的胜利者才有机会pk冠军. 解题思路:那么从1-16这个大的区间内诞生出来的冠军可能是来自左边,也可能是右边,然后再左边右边的子区间递归找出冠军.f[i][l][r]表示l-r这个区间的胜利者是i的概率,那么假设i在区间的最左边,f[i][l][r] = Sum(f[i][l][m

HDU 4968 Improving the GPA(dp)

HDU 4968 Improving the GPA 题目链接 dp,最大最小分别dp一次,dp[i][j]表示第i个人,还有j分的情况,分数可以减掉60最为状态 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, avg, n; double dp1[15][405], dp2[15][405]; double get(int x) { if

URAL 1167. Bicolored Horses (DP)

题目链接 题意 :农夫每天都会放马出去,然后晚上把马赶入马厩,于是让马排成一行入马厩,但是不想马走更多的路,所以让前p1匹入第一个马厩,p2匹马入第二个马厩…………但是他不想让他的任何一个马厩空着,所有的马都必须入马厩.有两种颜色的马,如果 i 匹黑马与 j 匹白马同在一个马厩,不愉快系数是 i * j,总系数就是k个系数相加.让总系数最小. 思路 : dp[i][j] 代表的是前 i 个马厩放 j 匹马的最小不愉快系数值. 1 //1167 2 #include <cstdio> 3 #in

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long

hdu4939 Stupid Tower Defense (DP)

2014多校7 第二水的题 4939 Stupid Tower Defense Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 366    Accepted Submission(s): 88 Problem Description FSF is addicted to a stupid tower defense game.