背包问题求具体方案

问题描述:

 

 

解法:

因为求具体的方案,我们就不能采取之前滚动数组优化版本的 01背包 ,因为这样会损失一些具体方案

因为要求字典序最小,那么我们肯定采取贪心策略(能选序号小的就选序号小的)

我们如果从前往后遍历所有的物品,那么最后 dp[n][m] 就是最后答案,那我们就得从后往前遍历才可以求的具体方案 ,但是这样所求的是字典序最大的

所以我们应该反一下,从后往前去遍历所有物品,这样dp[1][m]就是最后答案,那么我们就从前往后遍历就可以求具体方案,这样求的是字典序最小的

 

 

int n,m;
int dp[1010][1010],v[1010],w[1010];

int main() {
    cin >> n >> m;
    for (int i = 1;i <= n;i++)
        cin >> v[i] >> w[i];
    for (int i = n;i >= 1;i--) {
        for (int j = 0;j <= m;j++) {
            dp[i][j] = dp[i+1][j];
            if (j >= v[i])
                dp[i][j] = std::max(dp[i][j],dp[i+1][j-v[i]]+w[i]);
        }
    }
    int vol = m;
    for (int i = 1;i <= n;i++) {
        if (vol-v[i] >= 0 && dp[i][vol] == dp[i+1][vol-v[i]]+w[i]) {
            cout << i << " ";
            vol -= v[i];
        }
    }
    return 0;
}

 

posted @ 2020-02-02 16:50  _Ackerman  阅读(713)  评论(1编辑  收藏  举报