Time Limit: 1000MS |
Memory Limit: 10000K |
|
Total Submissions: 24132 |
Accepted: 8446 |
Description
N=3, n1=10, D1=100, n2=4, D2=50, n3=5, D3=10
means the machine has a supply of 10 bills of @100 each, 4 bills of @50 each, and 5 bills of @10 each.
Call cash the requested amount of cash the machine should deliver and write a program that computes the maximum amount of cash less than or equal to cash that can be effectively delivered according to the available bill supply of the machine.
Notes:
@ is the symbol of the currency delivered by the machine. For instance, @ may stand for dollar, euro, pound etc.
Input
cash N n1 D1 n2 D2 ... nN DN
where 0 <= cash <= 100000 is the amount of cash requested, 0 <=N <= 10 is the number of bill denominations and 0 <= nk <= 1000 is the number of available bills for the Dk denomination, 1 <= Dk <= 1000, k=1,N. White spaces can occur freely between the numbers in the input. The input data are correct.
Output
Sample Input
735 3 4 125 6 5 3 350
633 4 500 30 6 100 1 5 0 1
735 0
0 3 10 100 10 50 10 10
Sample Output
735
630
0
0
题意, 给你最大的钱数 Case ,和 nk 种不同的面值, 每种面值D1...DN 对应的数量 n1....nN, 找出不超过最大钱数Case
思路:多重背包
import java.io.*;
import java.util.*;
/*
*
* author : deng_hui_long
* Date : 2013-8-31
*
*/
public class Main {
int Case,n;
int dp[]=new int[1000000];
public static void main(String[] args) {
new Main().work();
}
void work(){
Scanner sc=new Scanner(new BufferedInputStream(System.in));
while(sc.hasNext()){
Case=sc.nextInt();
n=sc.nextInt();
if(n==0&&Case==0)
break;
Node node[]=new Node[n];
Arrays.fill(dp,0);
for(int i=0;i<n;i++){
int a=sc.nextInt();
int b=sc.nextInt();
node[i]=new Node(a,b);
}
for(int i=0;i<n;i++){
multiplePack(node[i].val,node[i].val,node[i].cost);
}
System.out.println(dp[Case]);
}
}
//多重背包
void multiplePack(int cost,int weight,int amount){
if(cost*amount>=Case)//超过最大的钱数,按完全背包处理
completePack(cost,weight);
else{//小于最大的钱数,按01背包处理
int k=1;
while(k<amount){
zeroOnePack(k*cost,k*weight);
amount-=k;
k<<=1;//左移一位,表示乘以2
}
zeroOnePack(amount*cost,amount*weight);
}
}
//完全背包
void completePack(int cost,int weight){
for(int i=cost;i<=Case;i++){
dp[i]=Math.max(dp[i],dp[i-cost]+weight);
}
}
//01背包
void zeroOnePack(int cost,int weight){
for(int i=Case;i>=cost;i--)
dp[i]=Math.max(dp[i],dp[i-cost]+weight);
}
class Node{
int cost;
int val;
Node(int cost,int val){
this.cost=cost;
this.val=val;
}
}
}