标签:
o o o o o o o o o o o o o o o o o o /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F\ /F/ \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \ / \
o o o | o o o o | o o o o o o | o o o o o /F\ /F\ /F\ | /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F\ /F\ | /F\ /F\ /F\ /F\ /F/ \ / \ / \ | / \ / \ / \ / \ | / \ / \ / \ / \ / \ / \ | / \ / \ / \ / \ / \
 , b0 = 0 and 1 <= k <= M, if there are M groups in total. Note that M can equal to 1.
, b0 = 0 and 1 <= k <= M, if there are M groups in total. Note that M can equal to 1.2 5 2 1 4 3 2 5 5 2 5 4 3 2 1
Case #1: 31 Case #2: No solution
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <algorithm>
using namespace std;
#define REP(_,a,b)  for(int _=(a); _<=(b);++_)
#define sz(s) (int)((s).size())
typedef long long ll;
const int maxn = 1e5+10;
int n,l;
ll dp[maxn];
struct Num{
	ll h;
	int idx;
	Num(ll h = 0,int idx = 0):h(h),idx(idx){}
	friend bool operator < (Num a,Num b){
		if(a.h!=b.h) return a.h < b.h;
		else return a.idx > b.idx;
	}
};
vector<Num> vN;
struct node{
	int lson,rson;
	ll maxx;
	int mid(){
		return (lson+rson)>>1;
	}
}tree[maxn*4];
void pushUp(int rt){
	tree[rt].maxx = max(tree[rt<<1].maxx,tree[rt<<1|1].maxx);
} 
void build(int L,int R,int rt){
	tree[rt].lson = L;
	tree[rt].rson = R;
	tree[rt].maxx = -1;
	if(L==R){	
		return;
	}
	int mid = tree[rt].mid();
	build(L,mid,rt<<1);
	build(mid+1,R,rt<<1|1);
}
void init(){
	vN.clear();
	memset(dp,-1,sizeof dp);
}
void update(int pos,int l,int r,int rt,ll x){
	if(l==r){
		tree[rt].maxx = x;
		return;
	}
	int mid = tree[rt].mid();
	if(pos<=mid){
		update(pos,l,mid,rt<<1,x);
	}else{
		update(pos,mid+1,r,rt<<1|1,x);
	}
	pushUp(rt);
}
ll query(int L,int R,int l,int r,int rt){
	if(L <=l && R >= r){
		return tree[rt].maxx;
	}
	int mid = tree[rt].mid();
	ll ret;
	bool flag = false;
	if(L <= mid){
		ret = query(L,R,l,mid,rt<<1);
		flag = true;
	}
	if(R > mid){
		if(flag){
			ret = max(ret,query(L,R,mid+1,r,rt<<1|1));
		}else{
			ret = query(L,R,mid+1,r,rt<<1|1);
		}
	}
	return ret;
}
void input(){
	scanf("%d%d",&n,&l);
	REP(_,1,n){
		ll h;
		scanf("%I64d",&h);
		vN.push_back(Num(h,_));
	}
	sort(vN.begin(),vN.end());
	build(0,n,1);
}
void solve(){
	update(0,0,n,1,0);
	REP(_,0,sz(vN)-1) {	
		int ni = vN[_].idx;
		ll nh = vN[_].h;
		ll tm = query(max(ni-l,0),ni-1,0,n,1);
		if(tm>=0){
			dp[ni] = tm+nh*nh;
			update(ni,0,n,1,dp[ni]-nh);
		}
		if(ni==n) break;
	}
	if(dp[n]<=0){
		printf("No solution\n");	
	}else{
		printf("%I64d\n",dp[n]);
	}
}
int main(){
	int ncase,T=1;
	cin >> ncase;
	while(ncase--){
		init();	
		input();
		printf("Case #%d: ",T++);
		solve();	
	}
	return 0;
} HDU4719-Oh My Holy FFF(DP线段树优化)
标签:
原文地址:http://www.cnblogs.com/mengfanrong/p/5173851.html