HDU 2844 Coins 多重背包
题目链接:
http://acm.hdu.edu.cn/showproblem.php?pid=2844
Coins
Memory Limit: 32768/32768 K (Java/Others)
输入
The input contains several test cases. The first line of each test case contains two integers n(1 ≤ n ≤ 100),m(m ≤ 100000).The second line contains 2n integers, denoting A1,A2,A3...An,C1,C2,C3...Cn (1 ≤ Ai ≤ 100000,1 ≤ Ci ≤ 1000). The last test case is followed by two zeros.
输出
For each test case output the answer on a single line.
样例输入
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
样例输出
8
4
题解
裸的多重背包,这里提供两种思路:
1、开个cntv数组维护一下第i个背包用了几次,限制一些非法的转移,像完全背包那一做一遍就ok。
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=101010;
int cntv[maxn];
bool dp[maxn];
int v[maxn],c[maxn];
int main() {
int n,m;
while(scf("%d%d",&n,&m)==2&&n){
clr(dp,0);
for(int i=1;i<=n;i++) scf("%d",&v[i]);
for(int i=1;i<=n;i++) scf("%d",&c[i]);
clr(dp,0);
dp[0]=1;
for(int i=1;i<=n;i++){
clr(cntv,0);
for(int j=v[i];j<=m;j++){
if(!dp[j]&&dp[j-v[i]]&&cntv[j-v[i]]<c[i]){
dp[j]=1;
cntv[j]=cntv[j-v[i]]+1;
}
}
}
int ans=0;
for(int i=1;i<=m;i++) ans+=dp[i];
prf("%d\n",ans);
}
return 0;
}
//end-----------------------------------------------------------------------
2、用二进制拆分转化成01背包。
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
include
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf
typedef long long LL;
typedef vector
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;
const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8;
const double PI = acos(-1.0);
//start----------------------------------------------------------------------
const int maxn=101010;
int cntv[maxn];
bool dp[maxn];
int v[maxn],c[maxn];
int main() {
int n,m;
while(scf("%d%d",&n,&m)==2&&n){
clr(dp,0);
for(int i=1;i<=n;i++) scf("%d",&v[i]);
for(int i=1;i<=n;i++) scf("%d",&c[i]);
VI arr;
for(int i=1;i<=n;i++){
int j=1;
//二进制拆分
while(c[i]>0){
if(c[i]>=j){
arr.pb(v[i]j);
c[i]-=j;
}else{
arr.pb(v[i]c[i]);
c[i]=0;
}
j<<=1;
}
}
clr(dp,0);
dp[0]=1;
for(int i=0;i<arr.sz();i++){
for(int j=m;j>=arr[i];j--){
dp[j]=dp[j]|dp[j-arr[i]];
}
}
int ans=0;
for(int i=1;i<=m;i++) ans+=dp[i];
prf("%d\n",ans);
}
return 0;
}
//end-----------------------------------------------------------------------

浙公网安备 33010602011771号