【暴力DP】2021 icpc上海 I

Problem - I - Codeforces

题意:

 

思路:

考虑暴力DP即可

设 dp[i][j][k]表示 前 i 个物品,已经翻倍了 j 次,A点数 - B点数为 k 的最大价值和

然后分为这6种决策分类讨论就好了

注意数组里不能有负数,要加个偏移量 P 

Code:

#include <bits/stdc++.h>

#define int long long

using i64 = long long;

constexpr int N = 1e2 + 10;
constexpr int M = 1e5 + 10;
constexpr int P = 2600;
constexpr i64 Inf = 1e18;
constexpr int mod = 1e9 + 7;
constexpr double eps = 1e-6;

int n, K;
int v[N], t[N];
int dp[N][N][5220];

void solve() {
    std::cin >> n >> K;
    for (int i = 1; i <= n; i ++) {
        std::cin >> v[i] >> t[i];
    }

    for (int i = 0; i <= n; i ++) {
        for (int j = 0; j <= K; j ++) {
            for (int k = -2600; k <= 2600; k ++) {
                int tk = k + P;
                dp[i][j][tk] = -Inf;
            }
        }
    }

    dp[0][0][0 + P] = 0;

    for (int i = 1; i <= n; i ++) {
        for (int j = 0; j <= K; j ++) {
            for (int k = -2600; k <= 2600; k ++) {
                int tk = k + P;
                if (j >= 1) dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j - 1][tk]);
                if (k - t[i] * 2 >= -2600 && j >= 1) dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j - 1][tk - t[i] * 2] + v[i]);
                if (k + t[i] * 2 <= 2600 && j >= 1) dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j - 1][tk + t[i] * 2] + v[i]);
                dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j][tk]);
                if (k - t[i] >= -2600) dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j][tk - t[i]] + v[i]);
                if (k + t[i] <= 2600) dp[i][j][tk] = std::max(dp[i][j][tk], dp[i - 1][j][tk + t[i]] + v[i]);
            }
        }
    }

    int ans = -Inf;
    for (int j = 0; j <= K; j ++) {
        ans = std::max(ans, dp[n][j][0 + P]);
    }

    std::cout << ans << "\n";
}
signed main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    
    int t = 1;

    while (t--) {
        solve();
    }
    
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值