码迷,mamicode.com
首页 > 其他好文 > 详细

uva3983

时间:2017-11-01 13:40:04      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:这一   复杂   枚举   想法   ons   blog   front   思维   include   

这是一道思维层层递进的题。

注意到N最大是100000,C最大是100,所以我们不能设时间复杂度为O(NC)的状态。

只能设O(N)的状态了。

设d(i)为从原点出发,将前i个垃圾全部扫完又回到原点的最小代价。(注意这里设的是从原点出发又回到原点,这是为了状态转移的方便而设)

经典的想法还是把前i个垃圾进行分割。

d(i) = min{d(j) + dist2origin[j + 1] + dist[j + 1,i] + dist2origin[i] | j <= i, w(j+1,i) <= C}

搞完前j个的代价 + 从原点移动到j+1的代价 + 从j+1扫到i的代价 + 从i回到原点的代价。条件是在拿着j+1到i这一堆垃圾的时候总总量小于等于C。

显然直接枚举是一个O(N2)的东西,我们想到dp加速。

怎么加速,把与j有关的东西抽取出来,每次取当前可以选的j中的最小值。(因为与i有关的值可以O(1)求出)

这就是利用了优先队列!

 

把j相关的量分离出来有:

d(i) = min(d(j) - total_dist[j+1]+dist2origin(j+1)) + total_dist[i] + dist2origin[i](j同样要满足上面的限制条件)

如果令func(j) = d(j) - total_dist[j + 1] + dist2origin[j+1]

则d(i) = min(func(j)) + total_dist[i] + dist2origin[i]

这个用优先队列搞就好了。

#include <cstdio>
#include <algorithm>

using namespace std;

const int maxn = 100005;

int t, C, n;

int dist2origin[maxn], total_dist[maxn], total_weight[maxn], f[maxn], q[maxn];

struct node
{
    int x, y, w;
}a[maxn];

int func(int i)
{
    return f[i] - total_dist[i + 1] + dist2origin[i + 1]; 
}

void solve()
{
    scanf("%d", &C);
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        scanf("%d%d%d", &a[i].x, &a[i].y, &a[i].w);
        dist2origin[i] = abs(a[i].x) + abs(a[i].y);
        total_dist[i] = total_dist[i - 1] + abs(a[i].x - a[i - 1].x) + abs(a[i].y - a[i - 1].y);
        total_weight[i] = total_weight[i - 1] + a[i].w;
    }
    int front = 1, rear = 1;
    for (int i = 1; i <= n; i++)
    {
        while (front <= rear && total_weight[i] - total_weight[q[front]] > C)//把已经不合适的队头元素清掉。
            front++;
        f[i] = func(q[front]) + total_dist[i] + dist2origin[i];//这样取出来的队头就是func值最小的元素。
        while (front <= rear && func(i) <= func(q[rear]))//保证队列是单调递增的。
            rear--;
        q[++rear] = i;//不要忘了
    }
    printf("%d\n", f[n]);
    if (t > 0) printf("\n");
}

int main()
{
    scanf("%d", &t);
    while (t--) solve();
    return 0;
}

时间复杂度O(N)

uva3983

标签:这一   复杂   枚举   想法   ons   blog   front   思维   include   

原文地址:http://www.cnblogs.com/yohanlong/p/7765616.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!