背包问题

01背包

  • 给你n种不同的物品,每个物品有自己的重量w[i],和价值v[i],如果每个物品只能拿一次,给你容量为m的背包,怎样才能取得最大价值?

一维数组解法关键代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
    int t,n,m,i,j;
    int v[1005],w[1005];
    int dp[1005];
    scanf("%d",&t);
    while(t--)//能重复执行几次 
    {
        memset(dp,0,sizeof(dp));//作用是在一段内存块中填充某个给定的值,它是对较大的结构体或数组进行清零操作的一种最快方法 ,此处是将dp内全置为0 
        scanf("%d%d",&n,&m);//n值物品的数量,m指容量 
        for(i=0;i<n;i++)
            scanf("%d",&v[i]);//v指价值 
        for(i=0;i<n;i++)
            scanf("%d",&w[i]);//w指重量 
        for(i=0;i<n;i++)
            for(j=m;j>=w[i];j--)
                dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
        printf("%d\n",dp[m]);
    }
    return 0;
}

参考:https://blog.csdn.net/qq_41117236/article/details/80986564
https://blog.csdn.net/FGY_u/article/details/87448544

骑士拿到工资(为一张N元的钞票,记住,只有一张钞票),为了防止下月自己在战斗中频繁的死掉,他会给自己买一些道具,于是他来到了地精商店的死亡骑士:“我要买道具!”我们这里有三种道具,血瓶150块一个,法药200块一个,药水350块一个”

完全背包问题

一维解决

public static void main(String[] args) {
        int w[] = {150, 200, 350};
        int v[]=w;//此处药品价格既是价值也是体积
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();//N为总钱数
        int[] dp=new int [N+1];
        for (int i = 0; i < w.length; i++) {
			for (int j = w[i]; j <=N; j++) {
				dp[j]=Math.max(dp[j], dp[j-w[i]]+v[i]);
			}
		}
        /*int[] max=new int[1];
        for (int i = 0; i < dp.length; i++) {
			max[0]=(max[0]>dp[i])?max[0]:dp[i];
		}*/
        System.out.println(N-dp[N]);
    }

二维解决

import java.util.ArrayList;
import java.util.Scanner;

public class test3 {
    static  void solve(int total_money) {
        int w[] = {150, 200, 350};
        int v[];
        v = w;
        int len = w.length;
        int c = total_money;
        int dp[][] = new int[len + 1][c + 1];
        int max[] = new int[len + 1];
        int max1=dp[0][0];
        for (int i = 1; i < len + 1; i++) {
            for (int j = 1; j < c + 1; j++) {
                if (j >= w[i - 1])
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - w[i - 1]] + v[i - 1]);
                else
                    dp[i][j] = dp[i - 1][j];
            }

        }
        for (int i = 1; i < len + 1; i++) {
            for (int j = 1; j < c + 1; j++)
               max[i]=Math.max(dp[0][0],dp[i][j]);
        }
        for (int i = 1; i < len + 1; i++) {
            max1=Math.max(max[0],max[i]);
        }
        System.out.print(total_money-max1+"\n");
    }

    public static void main(String args[])
    {
        Scanner in=new Scanner(System.in);
        int m=in.nextInt();
        ArrayList <Integer> list=new ArrayList();
        for(int i=0;i<m;i++)
        {
            int total_money=in.nextInt();
            list.add(total_money);
        }
        for(int i=0;i<list.size();i++) {
            solve(list.get(i));
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值