DP
预处理 f 1 [ i ] f1[i] f1[i]表示用 i i i的资源能得到的最大效率。因为苦工的数量无限制,那么这就是一个完全背包。
设 f 2 [ i ] [ j ] f2[i][j] f2[i][j]表示第 i i i时间剩下 j j j的资源能得到的最大效率。那么就可以借助 f 1 f1 f1进行转移了。
注意一有答案就要退出,不然会T。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 105
#define M 1005
using namespace std;
typedef long long LL;
int n,m,t; LL c[N],w[N],f1[M],f2[M][M];
int main(){
scanf("%d%d%d",&n,&m,&t);
if (m>=t) return puts("0"),0;
for (int i=1;i<=n;i++)
scanf("%lld%lld",&c[i],&w[i]);
memset(f1,-1,sizeof(f1)),f1[0]=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=t;j++)
if (j>=c[i]&&(~f1[j-c[i]]))
f1[j]=max(f1[j],f1[j-c[i]]+w[i]);
memset(f2,-1,sizeof(f2)),f2[0][m]=0;
for (int i=0;i<=t;i++){
if (~f2[i][t]) return printf("%d\n",i),0;
for (int j=0;j<=t;j++){
if (f2[i][j]==-1) continue;
for (int k=0;k<=j;k++){
if (f1[k]==-1) continue;
LL d=j-k+f2[i][j]+f1[k];
if (d>=t) return printf("%d\n",i+1),0;
f2[i+1][d]=max(f2[i+1][d],f2[i][j]+f1[k]);
}
}
}
return 0;
}