题意:
一个人,每天有食物供应,除了自己吃之外还可以给同学吃,或者将今天的食物留到明天,但不能留到后天。每天每个朋友只能喂一次,每喂一次加1点受欢迎度。求n天后的最大受欢迎度。
题解:
DP,记录昨天剩下多少食物,并且每天计算喂i个朋友的最小花费。注意食物不能留到第三天。
本来以为400^3要很久呢,没想到CF升级后这么快了。
//Time:62ms
//Memroy:3600KB
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <vector>
#include <map>
#include <queue>
#include <set>
#define MAXN 410
#define INF 1000000007
#define MP(x,y) make_pair(x,y)
#define FI first
#define SE second
#define EPS 1e-8
using namespace std;
int dp[MAXN][MAXN];
int a[MAXN],f[MAXN],top,who[MAXN];
int efa[MAXN][MAXN],eat[MAXN][MAXN];
pair<int,int> pa[MAXN*2],fa[MAXN][MAXN];
set<pair<int,int> >se;
int main()
{
//freopen("/home/moor/Code/input","r",stdin);
freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);
int n,v,m,ans,pos;
while(scanf("%d%d",&n,&v)==2)
{
for(int i=0;i<n;++i) scanf("%d",&a[i]);
scanf("%d",&m);
top=0;
for(int i=1;i<=m;++i)
{
int l,r;
scanf("%d%d%d",&l,&r,&f[i]);
pa[top++]=MP(r+1,-i);
pa[top++]=MP(l,i);
}
sort(pa,pa+top);
memset(dp,-0x3f,sizeof(dp));
dp[0][0]=0;
se.clear();
set<pair<int,int> >::iterator ite;
for(int i=0,j=0;i<n;++i)
{
while(j<top&&pa[j].FI==i+1)
{
int tmp=f[abs(pa[j].SE)];
if(pa[j].SE>0)
se.insert(MP(tmp,pa[j].SE));
else
se.erase(MP(tmp,-pa[j].SE));
++j;
}
ite=se.begin();
eat[i][0]=0;
for(int k=1;ite!=se.end();++k,++ite)
eat[i][k]=eat[i][k-1]+ite->FI,efa[i][k]=ite->SE;
for(int k=0,l=0;k<=(i>0?a[i-1]:0);++k)
if(dp[i][k]>=0&&k+a[i]>=v)
{
int tmp=k-v;
while((unsigned)l+1<=se.size()&&tmp-eat[i][l+1]>0) ++l;
tmp+=a[i];
for(int p=l;tmp-eat[i][p]>=0&&(unsigned )p<=se.size();++p)
if(dp[i+1][min(tmp-eat[i][p],a[i])]<dp[i][k]+p)
{
dp[i+1][min(tmp-eat[i][p],a[i])]=dp[i][k]+p;
fa[i+1][min(tmp-eat[i][p],a[i])]=MP(p,k);
}
}
}
ans=0,pos=0;
for(int i=0;i<MAXN;++i)
if(ans<=dp[n][i])
ans=dp[n][i],pos=i;
for(int i=n;i>0;--i)
{
pos=min(pos,a[i-1]);
who[i-1]=fa[i][pos].FI,pos=fa[i][pos].SE;
}
printf("%d\n",ans);
for(int i=0;i<n;++i)
{
printf("%d",who[i]);
for(int j=1;j<=who[i];++j)
printf(" %d",efa[i][j]);
printf("\n");
}
}
return 0;
}