一道dp
  • 板块灌水区
  • 楼主霄22332233
  • 当前回复0
  • 已保存回复0
  • 发布时间2021/3/25 13:05
  • 上次更新2023/11/5 01:38:48
查看原帖
一道dp
382593
霄22332233楼主2021/3/25 13:05

http://oj.importos.com/voj/p/1016 题目链接如上

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000;
int dp[N][N];
int n;
int main()
{

    //已知情况
    scanf("%d",&n);

    int m[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int v[10] = {1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
    for (int i = 1; i <= 10; i++) {
        for (int k = 0; k <= n; k++) //从0开始枚举容量 ,恰好装入容量为K,其获得的最大值
            // 其实从W[i]开始枚举即可 此时无需下面的if判断
        {
            dp[i][k] = dp[i - 1][k];//继承上一个的 最大价值及消耗的容量
            if (k >= m[i-1])//当前拥有容量大于消耗的容量
            {
                dp[i][k] = max(dp[i][k], dp[i][k - m[i-1]] + v[i-1]);//两种策略 不放第i件物品 和放入第i件物品
            }                                      //将上述改为 max(dp[i][k],dp[i][k-w[i]]+c[i]);即为完全背包问题

        }
    }
    cout << dp[10][n] << endl;

    return 0;
}

以上代码可过,但我有一个问题,就是下面的代码为嘛总有一个错误?

#include<iostream>
#include<algorithm>
using namespace std;
const int N=1000;
int dp[N][N];
int n;
int main()
{

    //已知情况
    scanf("%d",&n);

    int w[100] = {1,1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int val[100] = {0,1, 5, 8, 9, 10, 17, 17, 20, 24, 30};
    for (int i = 1; i <= 10; i++) {
        for (int j=n;j>=0;j--) //从0开始枚举容量 ,恰好装入容量为K,其获得的最大值
            // 其实从W[i]开始枚举即可 此时无需下面的if判断
        {
             if(j>=w[i]){
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+val[i]);
            }
            else {
                dp[i][j]=dp[i-1][j];
            }

        }
    }
    cout << dp[10][n] << endl;

    return 0;
}

感觉dp的话从后面开始让j循环比较好,但为什么第二段代码会有一个测试点错误?

2021/3/25 13:05
加载中...