[luogu2317 HNOI2005] 星际贸易 (dp)

传送门

Solution

两个dp分开处理,
第一问什么都不考虑直接dp
第二问还有些疑惑,姑且先留坑

Code

//By Menteur_Hxy
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
#define Re register
#define Ms(a,b) memset(a,(b),sizeof(a))
#define Fo(i,a,b) for(Re int i=(a),_=(b);i<=_;i++)
#define Ro(i,a,b) for(Re int i=(b),_=(a);i>=_;i--)
using namespace std;

inline int read() {
	int x=0,f=1;char c=getchar();
	while(!isdigit(c)) {if(c=='-')f=-f;c=getchar();}
	while(isdigit(c)) x=(x<<1)+(x<<3)+c-48,c=getchar();
	return x*f;
}

const int N=2010;
int n,m,R,L,ans1,val,ans2,now;
bool vis[N];
int A[N],B[N],S[N],P[N],F[N],f[N][N<<1],Q[N<<1][N],h[N<<1],t[N<<1];

int main() {
	n=read(),m=read(),R=read(),L=read(); R=min(R,2*n);
	Fo(i,1,n) A[i]=read(),B[i]=read(),S[i]=read(),P[i]=read(),F[i]=read();
	Fo(i,2,n) if(S[i]-S[i-1]>L) return puts("Poor Coke!"),0;
	Ms(f,128);f[0][0]=0;
	Fo(i,1,n) Fo(j,0,m) {
		f[i][j]=f[i-1][j];
		if(j>=A[i]) f[i][j]=max(f[i][j],f[i-1][j-A[i]]+B[i]);
	}
	Fo(i,1,m) if(f[n][ans1]<f[n][i]) ans1=i; val=f[n][ans1],now=ans1;
	Ro(i,1,n) if(f[i][now]!=f[i-1][now]) now-=A[i],vis[i]=1;
	Ms(f,127);f[0][R]=0;Q[R][t[R]++]=0;
	Fo(i,1,n) Fo(j,0,R) {
		if(P[i]&&j) f[i][j]=min(f[i][j],f[i][j-1]+P[i]);
		if(h[j+2]<t[j+2]) f[i][j]=min(f[i][j],f[Q[j+2][h[j+2]]][j+2]+F[i]);
		if(vis[i]) h[j]=t[j]=0;
		while(h[j]<t[j]&&f[Q[j][t[j]-1]][j]>=f[i][j]) t[j]--;
		Q[j][t[j]++]=i;
		while(h[j]<t[j]&&S[i+1]-S[Q[j][h[j]]]>L) h[j]++;
 	}
 	Fo(i,1,R) if(f[n][i]<f[n][ans2]) ans2=i;
 	if(f[n][ans2]>1e9) return puts("Poor Coke!"),0;
 	return printf("%d %d",val,val-f[n][ans2]),0;
}
原文地址:https://www.cnblogs.com/Menteur-Hxy/p/9756507.html