糯米

TI DaVinci, gstreamer, ffmpeg
随笔 - 167, 文章 - 0, 评论 - 47, 引用 - 0
数据加载中……

POJ 3038 Flying Right 贪心

这题不懂做,一开始想了一个动态规划的方法,复杂度很高。估计得几百ms。
看status,觉得肯定有很低复杂度的方法。
然后看了 Discuss ,看到某位大牛说的贪心方法,顿时恍然大悟,吗的实在太牛逼了。
这位大牛的解法如下:
想象自己是一个黑一日游的司机:
1.如果有乘客要上车,那么就让他上,收钱!
2.如果超载了,把距目的地最远的几个乘客踢下去,退钱。
3.行驶到下一站

照着这个方法编码,一开始速度很慢,后来改成用一个队列来维护车上的乘客,速度就很快了,还飚上榜了。

#include <stdio.h>
#include 
<stdlib.h>

#define MAX_N 10032
#define MAX_K 50032

struct slot_node {
    
int end, cap;
    
struct slot_node *next;
}
;
struct stat_node {
    
int idx[MAX_N], cnt[MAX_N], head, tail, tot;
}
;
struct slot_node *start[2][MAX_N], slots[MAX_K*2];
struct stat_node stat[2];
int K, N, C, left, right, slots_cnt, ans;

inline 
int min(int a, int b)
{
    
return a < b ? a : b;
}


inline 
void ins(int a, int b, int c, int d)
{
    
struct slot_node *t;

    
if (b > right)
        right 
= b;
    
if (a < left)
        left 
= a;
    t 
= &slots[slots_cnt++];
    t
->next = start[d][a];
    t
->end = b;
    t
->cap = c;
    start[d][a] 
= t;
}


inline 
void off(int d, int i)
{
    
struct stat_node *= &stat[d];

    
if (t->head == t->tail || t->idx[t->head] != i) 
        
return ;
    ans 
+= t->cnt[t->head];
    t
->tot -= t->cnt[t->head];
    t
->head++;
}


inline 
void del(struct stat_node *t)
{
    
int c;

    
while (t->tot > C) {
        c 
= min(t->tot - C, t->cnt[t->tail - 1]);
        t
->cnt[t->tail - 1-= c;
        t
->tot -= c;
        
if (!t->cnt[t->tail - 1])
            t
->tail--;
    }

}


inline 
void add(struct stat_node *t, int cap, int end)
{
    
int i, j;

    t
->tot += cap;

    
for (i = t->tail - 1; i >= t->head; i--{
        
if (t->idx[i] == end) {
            t
->cnt[i] += cap;
            
return ;
        }
 else if (t->idx[i] < end)
            
break;
    }

    i
++;
    t
->tail++;
    
for (j = t->tail - 1; j > i; j--{
        t
->idx[j] = t->idx[j - 1];
        t
->cnt[j] = t->cnt[j - 1];
    }

    t
->idx[i] = end;
    t
->cnt[i] = cap;
}


inline 
void on(int d, int i)
{
    
struct slot_node *s;
    
struct stat_node *= &stat[d];

    
for (s = start[d][i]; s; s = s->next) 
        add(t, s
->cap, s->end);
    del(t);
}


int main()
{
    
int i, a, b, c;

    freopen(
"e:\\test\\in.txt""r", stdin);

    scanf(
"%d%d%d"&K, &N, &C);
    left 
= N;
    
for (i = 0; i < K; i++{
        scanf(
"%d%d%d"&a, &b, &c);
        
if (a > b) 
            ins(N 
- a, N - b, c, 1);
        
else
            ins(a, b, c, 
0);
    }


    
for (i = left; i <= right; i++{
        off(
0, i);
        off(
1, i);
        on(
0, i);
        on(
1, i);
    }

    printf(
"%d\n", ans);

    
return 0;
}


posted on 2010-04-12 16:37 糯米 阅读(436) 评论(0)  编辑 收藏 引用 所属分类: POJ


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理