HDU 2844 Coins 多重背包

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=2844

Coins

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 32768/32768 K (Java/Others)
#### 问题描述 > Whuacmers use coins.They have coins of value A1,A2,A3...An Silverland dollar. One day Hibix opened purse and found there were some coins. He decided to buy a very nice watch in a nearby shop. He wanted to pay the exact price(without change) and he known the price would not more than m.But he didn't know the exact price of the watch. > > You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.

输入

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 VI;
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 VI;
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-----------------------------------------------------------------------

posted @ 2016-09-28 17:32  fenicnn  阅读(217)  评论(0)    收藏  举报