个人排位赛B

DP

链接

题意

给你n个物品,你有一个容量为W的背包,每一个物品都有它的重量和价值,让你从n个中选取若干个,使得总重量不超过背包的上限,而且使得价值最大。

题解

原本是贪心,太繁了,用DP

i是遍历到前i个时,j是转换后重量和,k就代表已经选了k个,这重量加上k * w1就等于原来的重量

dp代表最后的价值

解释

i是目前范围是1-i,j表示(转化后的重量)的总和是j,k表示目前已经选择了k个,比如如果w1=5,

我选了一个w[1]=5,w[2]=6两个,那就是dp[2][1][2]这个状态

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 1e9 + 7;
const ll mod = 1e9 + 7;
const int MAX = 3e2 + 100;
ll w[MAX], v[MAX];
ll dp[MAX][MAX][MAX];

int main() {
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%lld %lld", &w[i], &v[i]);
    }
    ll w1 = w[1];
    for(int i = 1; i <= n; i++) {
        w[i] -= w1;
    }
    for(int i = 1; i <= n; i++) {
        for(int j = 0; j <=  n; j++) {
            for(int k = 1; k <= n; k++) {
                if(j - w[i] >= 0) {
                    dp[i][j][k] = max(dp[i - 1][j][k], dp[i - 1][j - w[i]][k - 1] + v[i]);
                }
                else {
                    dp[i][j][k] = max(dp[i - 1][j][k], dp[i][j][k]);
                }
            }
        }
    }
    ll ans = 0; //一定是0
    for(int j = 0; j <=  n; j++) {
        for(int k = 1; k <= n; k++) {
            if(j + k * w1 <= m)
            ans = max(ans, dp[n][j][k]);
        }
    }
    printf("%lld\n", ans);
}

闲话

这B题我的思路还是有问题

这场个人赛,我很快出了A和C,因为都是没有什么算法要求的思维题(C的一血)

我的D题没带字典,有些关键字我看不大懂,就迷迷糊糊写了一发并查集的(后来队友也说是这么做的),wa3,然后不确定是不是题目读错,就不看了

可是B我还没有写出来,最终还是两题

我的代码实现能力太差了,以及读题能力

要不是有两道思维题,就要爆零了

无论如何,这个学期的训练就结束了。暑假加油!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值