analysis
我的思路
这道题第一眼看,是个完全背包
但是是求最小值?
hm&%&*@#!%&%^$…………
不如这样,把干草磅数作为收益,花销作为体积,再套一个完全背包模板
但是这个花销上限是多少??
!#@!##&%&@#!%&_%$…………
假设每个公司买一磅5000美元,那么最大开销就可能达到25000000美元…
!#@!##&%&@#!%#&%&@#!%&*_%^$…………
通过暴力二分,终于发现假设最大开销为225000勉强在本地上跑得过,于是就侥幸AC了
总感觉有点什么不对
题解的思路
嗯,完全背包,求最小值,还是设花销为收益,磅数为体积,只是改下方程
f
[
i
]
=
m
i
n
(
f
[
i
]
,
f
[
i
−
v
[
j
]
]
+
w
[
j
]
)
f[i]=min(f[i],f[i-v[j]]+w[j])
f[i]=min(f[i],f[i−v[j]]+w[j])
然后初值设一个-inf
由于是采购至少H磅干草,那么就有可能需要采购稍微多H磅但是多不过5000,因为如果多过5000,那么必定可以少买一次使得买到的磅数大于H且花费要少些
嗯,可以AC了
ε=(´ο`*)))唉,完虐啊
code
我的思路
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
ll h,n;
const int maxh=50000+10,maxn=100+10;
ll P[maxn],C[maxn];
const int maxc=500*500+10;
ll f[maxc];
inline ll DP(int V){
clean(f,0);
loop(i,1,n){
loop(j,C[i],V){
f[j]=max(f[j],f[j-C[i]]+P[i]);
}
}
loop(i,1,V)
if(f[i]>=h)return i;
}
int main(){
//freopen("datain.txt","r",stdin);
clean(P,0),clean(C,0);
scanf("%lld%lld",&n,&h);
loop(i,1,n)scanf("%lld%lld",&P[i],&C[i]);
printf("%lld\n",DP(225000));
return 0;
}
题解的思路(巨佬可以忽略逗比注释)
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(register int i=start;i<=end;++i)
#define anti_loop(i,start,end) for(register int i=start;i>=end;--i)
#define clean(arry,num) memset(arry,num,sizeof(arry))
#define ll long long
ll h,n;
const int maxh=50000+10,maxn=100+10;
ll P[maxn],C[maxn];
const int maxc=50000+5000+10;
ll f[maxc];
inline ll DP(){
clean(f,0x3f);f[0]=0;
loop(i,1,n){//f[i]指刚刚采购i磅干草的最小价格
loop(j,P[i],h+5000){//1.P[i]是因为第i个物品最小可以凑出P[i] 2.h+5000是因为若不能够刚刚凑出h磅,那么下一个可以凑出来的最优的数必然在h+5000以内
f[j]=min(f[j],f[j-P[i]]+C[i]);
}
}
/*loop(i,h,h+5000)
if(f[i]<9187201950435737471)
return f[i];*/
//这样写是错的,因为可能你多买一点比你少买一点还便宜
ll res=LONG_LONG_MAX;
loop(i,h,h+5000)
res=min(res,f[i]);
return res;
}
int main(){
//freopen("datain.txt","r",stdin);
clean(P,0),clean(C,0);
scanf("%lld%lld",&n,&h);
loop(i,1,n)scanf("%lld%lld",&P[i],&C[i]);
printf("%lld\n",DP());
return 0;
}