Doing Homework題解

Doing Homework題解

咱們最好預先處理好每一個時間節點知足條件的最小費用,
而後貪心的處理就行。
預處理呢,
能夠用揹包:\(f[i][j]:\)表示第i個時間點作了j噸做業的最小精力
可是咱們並很差進行截止日期的刪除操做,
因此咱們倒過來搞就好了。c++

#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;
}
相關文章
相關標籤/搜索