初识dp(简单背包)JAVA版

来源:互联网 发布:cocos2d js 棋牌源码 编辑:程序博客网 时间:2024/05/02 07:25

HDU 4508 湫湫系列故事——减肥记I

这是道完全背包的裸题。AC代码:

思路如下:这里用的是优化过后的一维数组。a[i]:第 i 件食物的幸福值,b[i]:第 i 件食物的卡路里,dp[i]:在 i 卡路里限制下的最大幸福值。

dp[j]=Math.max(dp[j], dp[j-b[i]]+a[i]),j>b[i].顺序遍历,这里刚好与01背包的优化相反,因为这里每种物品都可以有无数种。

import java.util.Scanner;public class Main{static Scanner scan=new Scanner(System.in);public static void main(String[] args){while(scan.hasNext()){int n=scan.nextInt();int a[]=new int[n+1];int b[]=new int[n+1];for(int i=1;i<=n;i++){a[i]=scan.nextInt();//幸福值b[i]=scan.nextInt();//卡路里}int m=scan.nextInt();long dp[]=new long[m+1];for(int i=1;i<=n;i++)//i 代表前 i 种食物for(int j=b[i];j<=m;j++)//j 代表第 i 种食物所拥有的卡路里dp[j]=Math.max(dp[j],dp[j-b[i]]+a[i]);System.out.println(dp[m]);}}}


POJ 1014 Dividing

这题可以套进多重背包,可以算是个多重背包的可行性问题吧,AC代码:

思路如下:当大理石们的价值为奇数时,直接不可能平;当大理石们的价值为偶数时,看看在不切割石头的情况下,能否分出价值为总价值一半的大理石。

a[i]:价值为 i 的大理石的个数,dp[i][j]:前 i 种大理石,放入价值容量为 j 的背包(汗,一不小心写出了背包O__O"…那就背包吧)还剩余多少第 i 种大理石,如果值为-1,则表示不可填满。

import java.util.Scanner;public class Main{static Scanner scan=new Scanner(System.in);public static void main(String[] args){int cas=0;while(scan.hasNext()){int a[]=new int[7];int sum=0;for(int i=1;i<a.length;i++){a[i]=scan.nextInt();sum+=i*a[i];}if(sum==0)break;System.out.println("Collection #"+(++cas)+":");if((sum&1)==1){System.out.println("Can't be divided.");System.out.println();}else{int total=sum>>1;int dp[][]=new int[7][total+1];dp[0][0]=0;for(int j=1;j<total+1;j++)dp[0][j]=-1;for(int i=1;i<=6;i++){for(int j=0;j<total+1;j++)if(dp[i-1][j]>=0)//如果前i-1种大理石能填满容量为 j 的背包,那么dp[i][j]=a[i];//用前 i 种大理石去填容量为 j 的背包,必定最多能剩下a[i]个第 i 种大理石else//否则~dp[i][j]=-1;//就先赋个-1吧~等后面再说for(int j=0;j<=total-i;j++)if(dp[i][j]>0)//如果前 i 种大理石填满了容量为 j 的背包,则dp[i][j+i]=Math.max(dp[i][j+i], dp[i][j]-1);//用前 i 种大理石填满容量为j+i的背包是可能的}System.out.println(dp[6][total]!=-1?"Can be divided.":"Can't be divided.");System.out.println();}}}}

0 0
原创粉丝点击