zoukankan      html  css  js  c++  java
  • I love sneakers! (分组背包变形 每组至少买一个)

    题目大意:

    一个人去买鞋,有k种牌子,每种牌子至少买一双鞋子。每双鞋子有标价跟实际价值。求用m多的钱买最多价值的鞋。

    n: 物品总数 ,m: 钱数, K: 牌子数  ,描述 s:牌号 , v:标价, w:价值

    解法:

    首先看到题目很容易感觉得到这像是一个分组背包,但是又有点不一样。因为分组背包我们对于每组的物品最多选一件

    所以我们的循环是这样的:

    但是现在是每组至少选一个

    仔细想一下,其实我们只需要把内层循环的顺序换一下就好了,因为我可以在之前选了的基础上再继续选

    设dp[k][v]  表示选前k组物品我用钱数为v 的情况下能取到的最大价值总和。

    那么我转移要么从前 k - 1 组转移  ,要么就是在当前 k 组选了基础上再继续选

    特别注意一下:

    这里必须把dp初始化为-1,或者-INF,dp[k][v] = -1 OR -INF 这是表示前k组用钱数为v还不能取到任何鞋。

    memset(dp, -1, sizeof(dp));
    没有一组的时候,无论你有多少money,当然此时的最大价值为0了
    for(int v = 0; v <= M; v++) dp[0][v] = 0;   //或者memset(dp[0],0,sizeof(dp[0]);

    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <string.h>
    #include <vector>
    #include <map>
    #include <stack>
    #include <set>
    #include <queue>
    #include <math.h>
    #include <cstdio>
    #include <iomanip>
    #include <time.h>
    
    #define LL long long
    #define INF 0x3f3f3f3f
    #define ls nod<<1
    #define rs (nod<<1)+1
    
    using namespace std;
    
    const int maxn = 1e5 + 10;
    
    struct Node {
        int v,w;
    };
    
    vector<Node> vec[15];
    int dp[15][10010];
    
    int main() {
        int n,m,k;
        while (~scanf("%d%d%d",&n,&m,&k)) {
            for (int i = 0;i < 15;i++) {
                vec[i].clear();
                for (int j = 0;j <= m;j++)
                    dp[i][j] = -INF;
            }
            for (int i = 0;i <= m;i++)
                dp[0][i] = 0;
            for (int i = 1;i <= n;i++) {
                int c,v,w;
                scanf("%d%d%d",&c,&v,&w);
                vec[c].push_back({v,w});
            }
            for (int i = 1;i <= k;i++) {
                for (int s = 0;s < vec[i].size();s++) {
                    for (int j = m;j >= vec[i][s].v;j--) {
                        dp[i][j] = max(dp[i][j],max(dp[i-1][j-vec[i][s].v],dp[i][j-vec[i][s].v])+vec[i][s].w);
                    }
                }
            }
            if (dp[k][m] < 0)
                printf("Impossible
    ");
            else
                printf("%d
    ",dp[k][m]);
        }
        return 0;
    }
  • 相关阅读:
    Java面向对象编程之异常处理机制
    LinkedList链式集合
    Java之反射机制
    适配器模式
    QuickHit
    Java之单例模式
    Java面向对象之接口
    多线程
    线程同步
    试题分析
  • 原文地址:https://www.cnblogs.com/-Ackerman/p/12264896.html
Copyright © 2011-2022 走看看