您的位置:首页 > 其它

bzoj1855: [Scoi2010]股票交易

2015-11-30 10:47 148 查看
背包

感觉省选怎么会考这么简单的东西呢 无聊去网上搜了一下 发现原来正解是单调队列来优化呀

不过带个log问题也不大

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>

using namespace std;

void setIO(const string& a) {
freopen((a+".in").c_str(), "r", stdin);
freopen((a+".out").c_str(), "w", stdout);
}

const int N = 2010, INF = 0x3f3f3f3f;

int f

, g
;

template<typename Q> void maxit(Q& x, const Q& y) {
if(x < y) x = y;
}

int main() {

int n, maxp, w, ap, bp, as, bs;
scanf("%d%d%d", &n, &maxp, &w);

memset(f, -0x3f, sizeof f);

f[1][0] = 0;

for(int sum, ok, k, i = 1; i <= n; i++) {
scanf("%d%d%d%d", &ap, &bp, &as, &bs);
memcpy(g, f[i], sizeof g);
int tmr = min(i + 1 + w, n + 1);
for(ok = 1, sum = 0, k = 1; ok; k <<= 1) {
if(sum + k <= as) sum += k;
else k = as - sum, ok = 0;
for(int j = maxp; j >= 0; j--) if(g[j] > -INF) {// buy
if(j + k <= maxp) maxit(g[j + k], g[j] - ap * k);
}
}
//        memcpy(g, f[i], sizeof g);
for(ok = 1, sum = 0, k = 1; ok; k <<= 1) {
if(sum + k <= bs) sum += k;
else k = bs - sum, ok = 0;
for(int j = 0; j <= maxp; j++) if(g[j] > -INF) {// sell
if(j - k >= 0) maxit(g[j - k], g[j] + bp * k);
}
}
for(int j = 0; j <= maxp; j++) {
maxit(f[i + 1][j], f[i][j]);
maxit(f[tmr][j], g[j]);
}
}
int ans = 0;
for(int i = 0; i <= maxp; i++) ans = max(ans, f[n + 1][i]);
printf("%d\n", ans);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: