概述
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]);
}
}
}
这题可以套进多重背包,可以算是个多重背包的可行性问题吧,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();
}
}
}
}
最后
以上就是从容长颈鹿为你收集整理的初识dp(简单背包)JAVA版的全部内容,希望文章能够帮你解决初识dp(简单背包)JAVA版所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复