一开始当成分组背包做,POJ也果断给了个TLE
到底还是对背包理解不够深入
只要将小火车头载客量当成一个背包就行了
#include<iostream>
#include <string>
#include<vector>
#include<algorithm>
#include<set>
#include<fstream>
#include<cmath>
using namespace std;
#define lch(i) ((i)<<1)
#define rch(i) ((i)<<1|1)
#define sqr(i) ((i)*(i))
#define pii pair<int,int>
#define mp make_pair
#define FOR(i,b,e) for(int i=b;i<=e;i++)
#define ms(a) memset(a,0,sizeof(a))
const int maxnum =50005;
int n,m;
struct node
{
int l,r;
int w;
}tree[maxnum];
int dp[maxnum][4];
int w[maxnum];
void build(int rt,int l,int r){
tree[rt].l=l;
tree[rt].r=r;
if(l==r){
tree[rt].w=w[l];
return;
}
int mid = (l+r)>>1;
build(lch(rt),l,mid);
build(rch(rt),mid+1,r);
tree[rt].w = tree[lch(rt)].w+tree[rch(rt)].w;
}
int query(int rt,int l,int r){
if(tree[rt].l==l&&tree[rt].r==r){
return tree[rt].w;
}
int mid = (tree[rt].l+tree[rt].r)>>1;
if(r<=mid) return query(lch(rt),l,r);
else if(l>mid) return query(rch(rt),l,r);
else return query(lch(rt),l,mid)+query(rch(rt),mid+1,r);
}
int main()
{
//ifstream fin("G:/1.txt");
int t;
scanf("%d",&t);
while(t--){
ms(dp);
ms(w);
scanf("%d",&n);
FOR(i,1,n) scanf("%d",&w[i]);
scanf("%d",&m);
build(1,1,n);
FOR(i,1,m){
FOR(j,1,3){
dp[i][j]=query(1,1,i);
}
}
FOR(i,m+1,n){
FOR(j,1,3){
dp[i][j]=max(dp[i-1][j],dp[i-m][j-1]+query(1,i-m+1,i));
}
}
int ans=0;
FOR(i,0,3){
ans = max(ans,dp[n][i]);
}
printf("%d\n",ans);
}
return 0;
}