poj1276

来源:互联网 发布:php经典案例 编辑:程序博客网 时间:2024/05/07 16:54
涉及算法:dp
题目描述:给定一个目标cash数目m,现在你拥有n种不同的cash分别编号1~n,不同种类的cash有着不同的面值v、数目a,现在从你所拥有的cash中任意抽取一些,使得总的cash数最接近m并且不大于m。
题目分析:很明显的多重背包问题
代码如下:
import java.io.IOException;import java.util.Arrays;import java.util.Scanner;public class Main_1276 {static int max;//目标cash数static int sort;//cash的面额种类数目static int[][] v;//v[i][0]:编号为i的cash的数目,v[i][1]:编号为i的cash的面额static int[] dp;//dp[i]:目标cash数目为i时,所能到达的最大的cash数目static int[] count;//public static void main(String[] args) throws IOException {Scanner in=new Scanner(System.in);while(in.hasNextInt()){max=in.nextInt();sort=in.nextInt();v=new int[sort+1][2];dp=new int[max+1];count=new int[max+1];for(int i=1;i<=sort;i++){v[i][0]=in.nextInt();v[i][1]=in.nextInt();}//dp();//dp2();dp3();System.out.println(dp[max]);}}//自顶向下,TLEstatic int dp(int res,int x){ //剩余值为res且只考虑第0~x种的面额所能得到 的最大值if(x==-1 || res==0) return 0;int q=-1;for(int i=0;i<=v[x][0];i++){if(res-v[x][1]*i>=0){q=Math.max(q,v[x][1]*i+dp(res-v[x][1]*i,x-1));}}return q;}//TLE//dp[i][j]:只考虑编号为1~i的cash,目标cash为j是,所能到达的最大的cash数目static void dp2(){int dp3[][]=new int[sort+1][max+1];int tmp;for(int i=1;i<=sort;i++){tmp=-1;for(int j=v[i][1];j<=max;j++){for(int k=0;k<=v[i][0];k++){if(j<k*v[i][1]){break;}else {if(dp3[i-1][j-k*v[i][1]]+k*v[i][1]>tmp){tmp=dp3[i-1][j-k*v[i][1]]+k*v[i][1];}}}dp3[i][j]=tmp;}}System.out.println(dp3[sort][max]);}//ACstatic void dp3(){for(int i=0;i<sort;i++)          {              Arrays.fill(count, 0);              for(int j=v[i][1];j<=max;j++)                       if(dp[j]<dp[j-v[i][1]]+v[i][1] && count[j-v[i][1]]<v[i][0])                  {                                                                   dp[j] = dp[j-v[i][1]]+v[i][1];                        count[j]=count[j-v[i][1]]+1;                   }          }  }}


0 0
原创粉丝点击