Doing Homework题解

Doing Homework题解

我们最好预先处理好每个时间节点满足条件的最小费用,
然后贪心的处理就行。
预处理呢,
可以用背包:\(f[i][j]:\)表示第i个时间点做了j吨作业的最小精力
但是我们并不好进行截止日期的删除操作,
所以我们倒过来搞就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=5006,M=5000;
int n,W,X,t,ans=0,val,o=0,f[2][N],dp[N];
struct hw{int x,w,t;}q[N];
inline int read(){
   int T=0,F=1; char ch=getchar();
   while(ch<'0'||ch>'9'){if(ch=='-') F=-1; ch=getchar();}
   while(ch>='0'&&ch<='9') T=(T<<3)+(T<<1)+(ch-48),ch=getchar();
   return F*T;
}
bool cmp(hw u,hw v){return u.t<v.t;}
int main(){
   X=read(),W=read(),n=read();
   for(int i=1;i<=n;++i) q[i].x=read(),q[i].w=read(),q[i].t=read();
   sort(q+1,q+n+1,cmp),memset(dp,0x3f,sizeof(dp)),memset(f,0x3f,sizeof(f));
   f[0][0]=f[1][0]=0;
   for(int i=n;i>=1;--i){
       o^=1;
       for(int j=0;j<=M;++j){
           f[o][j]=f[o^1][j];
           if(j>=q[i].w) f[o][j]=min(f[o][j],f[o][j-q[i].w]+q[i].x);
           if(j>=W) dp[i]=min(dp[i],f[o][j]);
       }
   }
   for(int i=1;i<=n;++i){
       if(q[i].t==q[i-1].t) continue;
       t=dp[i],val=X/t;
       if(val<q[i].t-q[i-1].t){ans+=val,X-=val*t; break;}
       else ans+=q[i].t-q[i-1].t,X-=(q[i].t-q[i-1].t)*t;
   }
   printf("%d %d\n",ans,X);
   return 0;
}
posted @ 2019-11-01 16:40  lsoi_ljk123  阅读(200)  评论(0编辑  收藏  举报