之前写的是判断完全背包和多重背包结果被卡掉两个点(不是TLE是WA我用了二进制分组优化)。
后面看了下题解把完全背包的代码也改成了多重背包,但是为什么最后两个点还是过不了而题解的过了?(好像两份代码没什么区别?)
这是我的代码:
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
int hs, ht, ms, mt, n, W, cur;
struct Item {
ll w, v;
} item[10005];
ll f[1000005];
int main() {
scanf("%d:%d %d:%d %d", &hs, &ms, &ht, &mt, &n);
W = (ht - hs) * 60 + (mt - ms);
for (int i = 1; i <= n; i++) {
int w, v, p;
scanf("%d %d %d", &w, &v, &p);
if (!p) p = 999999;
// 多重背包二进制分组优化
int c = 1;
while (p) {
p -= c;
item[++cur].w = w * c;
item[cur].v = v * c;
c *= 2;
if (p - c < 0) {
item[++cur].w = w * p;
item[cur].v = v * p;
break;
}
}
}
n = cur;
for (int i = 1; i <= n; i++) {
for (int j = W; j >= item[i].w; j--) {
f[j] = max(f[j], f[j-item[i].w] + item[i].v);
}
}
cout << f[W] << endl;
return 0;
}
这是题解的代码
#include<cstdio>
#include<algorithm>
#define re register int
using namespace std;
int nx,ny,ex,ey,n,f[1010];
int a[10005],b[10005],c[10005];
int tp,co[1000005],v[1000005];//尽可能开大,不要把空间开爆了
inline void pre() {
for(re i=1;i<=n;i++) {
int t=1;
while(c[i]) {
co[++tp]=t*a[i];
v[tp]=t*b[i];
c[i]-=t; t*=2;
if(c[i]<t) {//如果剩下的不能再拆,就直接放在一起
co[++tp]=a[i]*c[i];
v[tp]=b[i]*c[i];
break;
}
}
}
}
int main() {
scanf("%d:%d%d:%d%d",&nx,&ny,&ex,&ey,&n);
int t=(ex*60+ey)-(nx*60+ny);
for(re i=1;i<=n;i++) {
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(!c[i]) c[i]=999999;
}
pre();//二进制拆分
for(re i=1;i<=tp;i++) {//考虑每个拆出来的物品
for(re j=t;j>=co[i];j--)//01背包板子
f[j]=max(f[j],f[j-co[i]]+v[i]);
}
printf("%d",f[t]);
return 0;
}
求大佬指教qwq