版权声明:转载请声明出处,谢谢配合。 https://blog.csdn.net/zxyoi_dreamer/article/details/82532592
解析:
多重背包二进制拆分法板子题。
一种物品,多种个数对答案的影响显然可以拆分成 形式,那么复杂度直接降为 。
据说这道题有单调队列优化做法,以后再更。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
ll getint(){
re ll num=0;
re char c;
while(!isdigit(c=gc()));
while(isdigit(c))num=(num<<1)+(num<<3)+(c^48),c=gc();
return num;
}
inline
void outint(ll a){
static char ch[23];
if(a==0)pc('0');
while(a)ch[++ch[0]]=(a-a/10*10)^48,a/=10;
while(ch[0])pc(ch[ch[0]--]);
}
int n;
int b[201],c[201];
int a[4002],cnt;
int d[4002];
int k;
int f[20002];
int logn[20002];
int dp[20002];
int main(){
logn[1]=0;
for(int re i=2;i<=20000;++i){
logn[i]=logn[i>>1]+1;
}
n=getint();
for(int re i=1;i<=n;++i)b[i]=getint();
for(int re i=1;i<=n;++i)c[i]=getint();
k=getint();
for(int re kk=1;kk<=n;++kk){
for(int re i=0;i<=(logn[c[kk]]);++i){
a[++cnt]=(1<<i)*b[kk];
d[cnt]=(1<<i);
}
a[++cnt]=(c[kk]-(1<<logn[c[kk]]))*b[kk],d[cnt]=(c[kk]-(1<<logn[c[kk]]));
if(a[cnt]==0)--cnt;
}
memset(dp,0x3f,sizeof dp);
dp[0]=0;
for(int re i=1;i<=cnt;++i){
for(int re j=k;j>=a[i];--j){
dp[j]=min(dp[j],dp[j-a[i]]+d[i]);
}
}
cout<<dp[k]<<endl;
return 0;
}