算法很美01背包问题动态规划、贪心
题目描述
- Sidney想去Gandtom家玩。但Sidney家和Gandtom家之间是高低不平、坑坑洼洼的土路。所以他需要用他的背包装几袋稀的泥,在路上铺平一些干的土,使路变成平整的泥土,才能到Gandtom家见到Gandtom。
已知现在有n种稀的泥,第i种稀的泥的质量为wi,体积为vi。Sidney的包能装体积不超过V的稀的泥。Sidney出门时携带的稀的泥的质量应该尽可能的大。在此前提下,携带的稀的泥的体积也应该尽可能的大。
试求Sidney最多能携带多少质量的稀的泥与此时的最大体积上路。 - Input
第一行有一个整数T,表示组数。
每组数据第一行有两个正整数n、V(0<n,V<=103) 。
每组数据第二行有个n正整数,第i个数为wi(0<wi<=106)。
每组数据第三行有个n正整数,第i个数为vi(0<vi<=103) - Output
每组样例第一行输出两个整数。表示Sidney最多能携带多少质量的稀的泥与此时的最大体积上路。
Sample Input
2
5 3
1 2 3 4 5
1 1 1 1 1
3 7
1 2 1
3 5 3
Sample Output
12 3
2 6
题目解析
- 该题用贪心不好保证两个都最大,dp数组每个单元格表示,有j种水泥和i个背包容量的最优装载情况,在dp数组中可以通过dfs寻找每次“选择”的水泥(不过时间复杂度有些高)
代码
Scanner scanner=new Scanner(System.in);
int T=scanner.nextInt();
for (int i = 0; i < T; i ) {
int n=scanner.nextInt();
Shuini[] samples=new Shuini[n];
int V=scanner.nextInt();
for (int j = 0; j < n; j ) {
samples[j]=new Shuini(scanner.nextInt(),0);
}
for (int j = 0; j < n; j ) {
samples[j].vi=scanner.nextInt();
samples[j].getUnitValue();
}
//贪心算法(无法保证w,v同时最大)
//solve(samples,V);
//dp动规划
solve1(samples,V);
}
}
private static void solve1(Shuini[] samples, int v) {
int[][] dp=new int[samples.length][v 1];
//初始化dp
for (int i = 0; i < dp.length; i ) {
//当背包没有容量的时候全部初始化为0
dp[i][0]=0;
}
boolean falg=false;
for (int i = 0; i < dp[0].length; i ) {
if (falg) {
dp[0][i]= samples[0].vi;
continue;
}
if (i>=samples[0].vi) {
dp[0][i]= samples[0].vi;
falg=true;
}else {
dp[0][i]=0;
}
}
//获取最大质量
for (int i = 1; i < dp.length; i ) {
for (int j = 1; j < dp[0].length; j ) {
//当前背包装得下
if(j>=samples[i].vi) {
int yao=samples[i].wi dp[i-1][j-samples[i].vi];
int buyao=dp[i-1][j];
dp[i][j]=max(yao,buyao);
}else {//当前背包装不下
dp[i][j]=dp[i-1][j];
}
}
}
//dfs(samples,dp,0,0,0);
//获取背包装载最大v值
System.out.println(dp[dp.length-1][v]);
}
private static int dfs(Shuini[] samples,int[][] dp, int x, int y,int maxV) {
if(dp[x][y]==samples[x].wi) {
maxV =samples[x].vi;
return maxV;
}
for (int i =dp.length-1 ; i >=0; i ) {
for (int j = dp[0].length-1; j >= 0; j ) {
//有可能出现要的情况(出现选和没选答案相同的情况)
if(dp[x][y]-samples[x].wi-dp[x-1][y-samples[x].vi]==0) {
maxV =samples[x].vi;
int xuanle=dfs(samples,dp, x-1, y-samples[x].vi,maxV);
//回溯;
maxV-=samples[x].vi;
int meixuan=dfs(samples, dp, x-1, y,maxV);
maxV =max(xuanle,meixuan);
}
}
}
return maxV;
}
private static int max(int yao, int buyao) {
if (yao>=buyao) {
return yao;
}
return buyao;
}
//贪心算法,贪心失败//无法保持 质量和体积都最大
//仅能保持质量最大
private static void solve(Shuini[] samples,int V) {
int maxWeight=0;
int leftV=V;
Arrays.sort(samples);
Arrays.toString(samples);
for (int i = 0; i < samples.length; i ) {
if (leftV==0) {
System.out.print(maxWeight " ");
System.out.println(V);
return;
}
if(samples[i].vi<=leftV) {
leftV-=samples[i].vi;
maxWeight =samples[i].wi;
}
}
System.out.print(maxWeight " ");
System.out.println(V-leftV);
}
private static class Shuini implements Comparable<Shuini>{
int wi;
int vi;
int unitW;
private void getUnitValue() {
unitW = wi/vi;
}
//单位质量大的放前面,单位质量相同的,体积小的放后面
@Override
public int compareTo(Shuini o) {
if(this.unitW>o.unitW) {
return -1;
}else if (this.unitW==o.unitW) {
return (int) (o.vi-this.vi);
}else {
return 1;
}
}
public Shuini(int wi, int vi) {
super();
this.wi = wi;
this.vi = vi;
}
@Override
public String toString() {
return "Shuini [wi=" wi ", vi=" vi ", unitW=" unitW "]";
}
}
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhggbeac
系列文章
更多
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01 -
怎样阻止微信小程序自动打开
PHP中文网 06-13