题解 P2948
此题为比较基础的一道DP
楼上题解的做法都是二维DP或记搜,我这里推荐一种一维DP的方法。
我们观察到能力值是绝对的,而不是增长值,且能力值非常小。所以我们考虑把课程按照开始时间进行排序,再用
然后我们用动态规划,用
以上我们可以得出这题的状态转移方程:
最终代码如下:
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x3f3f3f3f
const ll N=110000;
const ll M=110;
ll t,m,n,ans;
ll dp[N],sum[N];
struct Nodem{ll t,s,c;}x[M];
bool cp(Nodem PRO,Nodem PRE){return PRO.t==PRE.t?PRO.s<PRE.s:PRO.t<PRE.t;}
int main()
{
memset(sum,inf,sizeof(sum));
scanf("%lld%lld%lld",&t,&m,&n);
for(ll i=1;i<=m;i++) scanf("%lld%lld%lld",&x[i].t,&x[i].s,&x[i].c);
for(ll i=1,u,v;i<=n;i++) scanf("%lld%lld",&v,&u),sum[v]=min(sum[v],u);
sort(x+1,x+1+m,cp);
x[0].t=1;x[0].s=0;x[0].c=1;x[m+1].t=t+1;
for(ll i=1;i<=M;i++) sum[i]=min(sum[i-1],sum[i]);
for(ll i=1;i<=m+1;i++)
for(ll j=0;j<i;j++)
dp[i]=max(dp[i],dp[j]+(x[i].t-x[j].s-x[j].t)/sum[x[j].c]);
printf("%lld\n",dp[m+1]);
return 0;
}