题目地址


易错点:

  • 需要掌握单调队列优化DP的基本方法.
  • 题目直接给出的数据在初始化时经常需要进行排序处理.

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int MAXN=32000,MAXM=200;
int f[MAXM][MAXN],q[MAXN];
struct rec{
	int l,p,s;
	bool operator <(rec another)const{
		return s<another.s;
	}
}a[MAXM];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d%d",&a[i].l,&a[i].p,&a[i].s);
	}
	sort(a+1,a+m+1);
	for(int i=1;i<=m;i++){
		int l=1,r=0;
		for(int k=max(0,a[i].s-a[i].l);k<=a[i].s-1;k++){
			while(l<=r&&f[i-1][k]-k*a[i].p>=f[i-1][q[r]]-q[r]*a[i].p)r--;
			q[++r]=k;
		}
		for(int j=1;j<=n;j++){
			f[i][j]=max(f[i-1][j],f[i][j-1]);
			if(j>=a[i].s){
				while(l<=r&&j-q[l]>a[i].l)l++;
				if(l>r)continue;
				f[i][j]=max(f[i][j],f[i-1][q[l]]+(j-q[l])*a[i].p);
			}
		}
	}
	printf("%d\n",f[m][n]);
	return 0;
}