HDU 5550 - Game Rooms(DP + 前缀和预处理)

链接:

http://acm.hdu.edu.cn/showproblem.php?pid=5550

题意:

一个大楼有n(2≤n≤4000)层,每层可以建一个乒乓球房或者一个游泳房,且每种房间在大楼里至少要有一个。
已知每层有ti个乒乓球运动员和pi个游泳运动员(1≤ti,pi≤1e9)。
问怎样建房,才能使得所有运动员到相应房间的总距离最小,输出最小值。

分析:

因为每种房间在大楼里至少要有一个,所以肯定会有这样一种状态:第i层是一种房间,第i+1层是另一种房间。
所以可以设d[i][x]:第i层是x房间,且第i+1层是另一种房间时,前i层的最优解。
则状态转移方程为:d[i][x] = min(d[k][x^1] + 第k+1~i层都是x房间时所产生的最小总距离),1≤k<i。
其中x^1表示另一种房间,求第L~R层都是x房间时所产生的最小总距离可以用前缀和预处理,具体看代码。
BTW,此题为2015年CCPC的银牌题。

代码:

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4
 5 typedef long long int LLI;
 6 const LLI INF = 0x3f3f3f3f3f3f3f3f;
 7 const int UP = 4000 + 5;
 8 LLI sum[UP][2]; // sum[i][x]:前i层x运动员的总人数
 9 LLI dist[UP][2]; // dist[i][x]:前i层所有x运动员到第0层的总距离
10 LLI d[UP][2]; // d[i][x]:第i层是x房间,且第i+1层是另一种房间时,前i层的最优解
11
12 LLI toLeft(int L, int R, int x) { // 第L~R层的所有x运动员到第L-1层的总距离
13     return (dist[R][x]-dist[L-1][x]) - (sum[R][x]-sum[L-1][x]) * (L-1);
14 }
15
16 LLI toRight(int L, int R, int x) { // 第L~R层的所有x运动员到第R+1层的总距离
17     return (sum[R][x]-sum[L-1][x]) * (R+1) - (dist[R][x]-dist[L-1][x]);
18 }
19
20 LLI process(int L, int R, int x) { // 第L~R层的所有x运动员到第L-1层或R+1层的总距离最小值
21     int M = L + (R-L)/2;
22     return toLeft(L, M, x) + (M+1>R ? 0 : toRight(M+1, R, x));
23 }
24
25 int main() {
26     int T, n;
27     LLI t, p;
28     scanf("%d", &T);
29     for(int cases = 1; cases <= T; cases++) {
30         scanf("%d", &n);
31         for(int i = 1; i <= n; i++) {
32             scanf("%lld%lld", &t, &p);
33             sum[i][0] = sum[i-1][0] + t;
34             sum[i][1] = sum[i-1][1] + p;
35             dist[i][0] = dist[i-1][0] + t*i;
36             dist[i][1] = dist[i-1][1] + p*i;
37         }
38         LLI ans = INF;
39         for(int i = 1; i < n; i++) {
40             d[i][0] = toRight(1, i, 1); // 前i层都是0房间,第i+1层是1房间的总距离
41             d[i][1] = toRight(1, i, 0); // 前i层都是1房间,第i+1层是0房间的总距离
42             for(int k = 1; k < i; k++) {
43                 d[i][0] = min(d[i][0], d[k][1] + process(k+1,i,1)); // 第k+1~i层都是0房间
44                 d[i][1] = min(d[i][1], d[k][0] + process(k+1,i,0)); // 第k+1~i层都是1房间
45             }
46             ans = min(ans, d[i][0] + toLeft(i+1,n,0)); // 后i+1层都是1房间
47             ans = min(ans, d[i][1] + toLeft(i+1,n,1)); // 后i+1层都是0房间
48         }
49         printf("Case #%d: %lld\n", cases, ans);
50     }
51     return 0;
52 }

原文地址:https://www.cnblogs.com/hkxy125/p/9784927.html

时间: 2024-11-20 04:15:04

HDU 5550 - Game Rooms(DP + 前缀和预处理)的相关文章

[ACM] hdu 3555 Bomb (数位DP,统计1-N中含有“49”的总数)

Bomb Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 7187 Accepted Submission(s): 2512 Problem Description The counter-terrorists found a time bomb in the dust. But this time the terrorists impro

hdu 4089 不错的DP 北京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4089 还有疑惑,需要重新推: 但是学到的: 1.A=a+b+c  abc是三种情况,那么P(A)=a*P(a->事件)+b*P(b->事件)+c*P(c->事件); a->事件意思是 在a情况下的事件,就是全概率公式的思想吧 2.一定注意每一步会不会出现分母为0 的情况,以及预处理的时候对于一些特殊情况导致自己的式子会出现分母为0的排除掉 3.概率DP经常出现推出了式子但是自己不会写代码的情况,

hdu 4945 2048 (dp+组合数)

2048 Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 840    Accepted Submission(s): 199 Problem Description Teacher Mai is addicted to game 2048. But finally he finds it's too hard to get 2048.

HDU 1227 Fast Food (DP)

题目链接 题意 : 有n个饭店,要求建k个供应点,要求每个供应点一定要建造在某个饭店的位置上,然后饭店都到最近的供应点拿货,求出所有饭店到最近的供应点的最短距离. 思路 : 一开始没看出来是DP,后来想想就想通了.预处理,如果要在下标为 i 到 j 的饭店建一个供应点,那一定是在下标为(i+j)/2的位置建造的,状态转移方程:dp[i][j] = dp[i-1][k-1]+dis[k][j](i <= k <= j) ,dp[i][j]代表的是在前 j 个饭店中建了 i 个供应点的最小距离.方

HDU 5172 GTY&#39;s gay friends (预处理+线段树)

题目链接:HDU 5172 GTY's gay friends 题意:给出一串序列,询问[l,r]区间里是否存在1~l-r+1的一个排列. 思路:1~l-r+1的一个排列 等价于 [l,r]中元素互不相同且[l,r]区间和等于(1+len)*len/2(len=l-r+1). 区间和可以用前缀和来处理. 元素互不相同,记录位置i上a[i]上次出现的位置记做pre[i],再用线段树来维护区间的pre最大值,若最大值小于l说明[l,r]中元素互不相同.(区间[l,r]中的每个pre[i]小于l说明区

HDU 4960 (水dp)

Another OCD Patient Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morning, his children played with plasticene. They broke the plasticene into N pieces, and put them in a line. Each piece has a volume Vi. Since Xi

HDU 1087 &amp;&amp; POJ 2533(DP,最长上升子序列).

~~~~ 两道题的意思差不多,HDU上是求最长上升子序列的和,而POJ上就的是其长度. 貌似还有用二分写的nlogn的算法,不过这俩题n^2就可以过嘛.. ~~~~ 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1087 http://poj.org/problem?id=2533 ~~~~ HDU1087: #include<cstdio> #include<cstring> #include<algorithm> #

hdu 2296 aC自动机+dp(得到价值最大的字符串)

Ring Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 3180    Accepted Submission(s): 1033 Problem Description For the hope of a forever love, Steven is planning to send a ring to Jane with a rom

hdu 2457 AC自动机+dp

DNA repair Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2004    Accepted Submission(s): 1085 Problem Description Biologists finally invent techniques of repairing DNA that contains segments c