• 博客园logo
  • 会员
  • 周边
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • YouClaw
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
HaibaraAi
博客园    首页    新随笔    联系   管理    订阅  订阅

Warm up 13 [A] Arranging Heaps

 

Arranging Heaps
Time Limit: 2000ms, Special Time Limit:5000ms, Memory Limit:65536KB
Total submit users: 8, Accepted users: 4
Problem 12748 : No special judgement

Problem description

斜率DP- -,就是维护一个上凸折线,把n^3优化到n^2了,反正都要先写dp方程,再化化啊,找点规律啊啥的- -!

A mining company extracts terbium, a rare metal used for constructing lightweight magnets, from river sand. They mine the Long River at N mining points, each of them identified by its distance from the river source. At each mining point, a relatively small but highly valued heap of mineral ore is extracted from the river.
To collect the mineral ore, the company regroups the N produced heaps into a smaller number of K heaps, each located at one of the initial mining points. The newly formed heaps are then collected by trucks.
To regroup the N heaps, they use a barge, which in practice can carry any amount of mineral ore because it is very large. The barge starts at the river source and can only travel downriver, so the heap produced at a mining point X can be taken to a mining point Y only if Y > X. Each heap is moved completely to another mining point, or not moved at all. The cost of moving a heap of weight W from a mining point X to a mining point Y is W × (Y - X). The total cost of the regrouping is the sum of the costs for each heap movement. Notice that a heap which is not moved has no inuence on the total cost.
Given the values for N and K, the N mining points, and the weight of the heap each mining point produced, write a program that calculates the minimum total cost to regroup the N initial heaps into K heaps.


Input
Each test case is described using several lines. The first line contains two integers N and K denoting respectively the number of initial heaps and the desired number of heaps after regrouping (1 ≤ K < N ≤ 1000). Each of the next N lines describes one of the initial heaps with two integers X and W indicating that the mining point X produced a heap of weight W (1 ≤ X;W ≤ 106). Within each test case the heaps are given in strictly ascending order considering their mining points.


Output
For each test case output a line with an integer representing the minimum total cost to regroup the N initial heaps into K heaps.


Sample Input
3 1
20 1
30 1
40 1
3 1
11 3
12 2
13 1
6 2
10 15
12 17
16 18
18 13
30 10
32 1
6 3
10 15
12 17
16 18
18 13
30 10
32 1
Sample Output
30
8
278
86
Problem Source
Latin American 2012

Submit   Discuss   Judge Status  Problems  Ranklist 

 

 1 #include <cstdio>
 2 #include <queue>
 3 #include <cstring>
 4 #include <algorithm>
 5 using namespace std;
 6 #define ll long long
 7 #define maxn 1005
 8 ll n, m, ans;
 9 ll dp[maxn][maxn];
10 ll sw[maxn], swx[maxn], a[maxn], p[maxn];
11 struct point{ 
12     ll x, y;
13     point(ll a=0, ll b=0) :x(a), y(b){}
14     point operator - (const point &r)const{ return point(x - r.x, y - r.y); }
15     ll operator * (const point &r)const{ return x*r.y - y*r.x; }
16 };
17 struct dequeue{
18     int head, tail;
19     point q[maxn];
20     void init(){ head = 1; tail = 0; }
21     void push(point t){
22         while (head<tail&&(q[tail]-q[tail-1])*(t-q[tail-1])<=0)tail--;
23         q[++tail] = t;
24     }
25     point pop(ll k){
26         while (head<tail&&k*q[head].x+q[head].y>=k*q[head+1].x+q[head+1].y)head++;
27         return q[head];
28     }
29 }qq;
30 ll solve(){
31     for (int i = 1; i <= n; i++)sw[i] = sw[i - 1] + a[i];
32     for (int i = 1; i <= n; i++)swx[i] = swx[i - 1] + p[i] * a[i];
33     memset(dp, 0, sizeof dp);
34     for (int i = 1; i <= n; i++)dp[1][i] = p[i] * sw[i] - swx[i];
35     for (int j = 2; j <= m; j++){
36         qq.init();
37         qq.push(point(sw[j-1],swx[j-1]+dp[j-1][j-1]));
38         for (int i = j; i <= n; i++){
39             point t = qq.pop(-p[i]);
40             dp[j][i] = p[i] * sw[i] - swx[i] - p[i] * t.x + t.y;
41             qq.push(point(sw[i],swx[i]+dp[j-1][i]));
42         }
43     }
44     return dp[m][n];
45 }
46 int main(){
47     while (~scanf("%I64d%I64d", &n, &m)){
48         for (int i = 1; i <= n; i++)scanf("%I64d%I64d", &p[i],&a[i]);
49         ans=solve();
50         printf("%I64d\n", ans);
51     }
52     return 0;
53 }
View Code
posted @ 2013-10-28 15:28  HaibaraAi  阅读(181)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2026
浙公网安备 33010602011771号 浙ICP备2021040463号-3