您的位置:首页 > 其它

[CF355C]Vasya and Robot(思维,贪心)

2016-11-22 19:56 447 查看
题目链接:http://codeforces.com/contest/355/problem/C

题意:1~n n个物品各重wi,现在有一个人可以从左边拿和从右边拿, 左边拿一个物品的花费是l*wi,从右边拿是r*wi。然后如果有一次从左边拿的上一次操作也是从左边拿的,就要额外花费ql,同理右边,问最小花费。

眼瞎胡乱跑了一发dp结果T了…

仔细观察就会发现,题意说的是…左手一定从最左边拿,右手一定从最右边拿……

那么一定有一个点,这个点的左手边全是左手拿的,右手边都是右手拿的。

那么枚举这个点,然后再判断这个点左手拿比较好还是右手拿比较好。由于代价都一样,所以可以先计算出两边的分别代价,然后算算某一侧比另一侧多了多少个,也就是需要额外q的花费的个数,贪心地认为这区间是交叉着取的,那么就最后算算多少个q花费就行了。

1 #include <bits/stdc++.h>
2 using namespace std;
3
4 typedef long long LL;
5 const LL maxn = 100100;
6 const LL inf = 0x7f7f7f7f;
7 int n, l, r, ql, qr;
8 int w[maxn];
9 LL ls[maxn], rs[maxn];
10 LL ret;
11
12 int main() {
13     // freopen("in", "r", stdin);
14     while(~scanf("%d%d%d%d%d",&n,&l,&r,&ql,&qr)) {
15         memset(ls, 0, sizeof(ls));
16         memset(rs, 0, sizeof(rs));
17         for(int i = 1; i <= n; i++) scanf("%d", &w[i]);
18         for(int i = 1; i <= n; i++) ls[i] = ls[i-1] + w[i] * l;
19         for(int i = n; i >= 1; i--) rs[i] = rs[i+1] + w[i] * r;
20         ret = inf;
21         for(LL i = 1; i <= n; i++) {
22             LL s = ls[i-1] + rs[i+1];
23             LL ln = i - 1, rn = n - i;
24             if(ln > rn) ret = min(ret, s+(ln-rn-1)*ql+min(w[i]*l+ql,w[i]*r));
25             else if(ln < rn) ret = min(ret, s+(rn-ln-1)*qr+min(w[i]*l,w[i]*r+qr));
26             else ret = min(ret, s+min(w[i]*l,w[i]*r));
27         }
28         printf("%I64d\n", ret);
29     }
30     return 0;
31 }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: