首页 > 试题广场 >

手写代码:01背包

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
#define re register
const int maxn = 2e4+7;
int n,m,v[maxn],val[maxn],dp[1001][maxn],ans;
int main()
{
    scanf("%d%d",&n,&m);
    for(int i = 1;i <= m;i++)
        scanf("%d%d",&v[i],&val[i]);
    for(int i = 1;i <= m;i++)
    {
        for(int j = 1;j <= n;j++)
        {
            if(v[i]>j)
            dp[i][j] = dp[i-1][j];//这一步十分重要,如果后面的物品的重量比前面i-1的小,就可以继承下来
            else
            dp[i][j] = max(dp[i-1][j],dp[i-1][j-v[i]]+val[i]);
        }
    }
    cout<<dp[m][n];
}
发表于 2020-12-14 00:32:55 回复(0)
//使用动态 规划 public static void main(String[] args) { //每个物品的重量  int[] w = new int[]{2, 1, 3, 2}; //每个物品的价值  int[] v = new int[]{3, 2, 4, 2}; int n=w.length; int total=5; //1)状态的定义  //dp[i][j] --->取前i个物品在容量为j的时候所能获得的最大值  int[][] dp = new int[n][total+1]; //2)初始值  //给第1行赋值  for (int i = 0; i <dp[0].length ; i++) { if (i>=w[0]){
            dp[0][i]=v[0];
        }else {
            dp[0][i]=0;
        }
    } //3状态转移方程  for (int i = 1; i <dp.length; i++) { for (int j = 0; j <total+1 ; j++) { //能放下  if (j>w[i]){ // int v1=v[i]+dp[i-1][j-w[i]]; //不选  int v2=dp[i-1][j];
                dp[i][j]=Math.max(v1,v2);
            }else {
                dp[i][j]=dp[i-1][j];
            }
        }
    }
    System.out.println(dp[n-1][total]);
}
发表于 2020-03-02 10:51:04 回复(0)