2021牛客寒假算法基础集训营6 - - G 机器人(状压dp解法)

有一说一,这场裸题签到题真不少。
这场稍微把G拿出来说一下。
G是状压dp的入门题,恶心就恶心在数据范围能到2021

这道题给了我们20组运算,我们用(1<<21)来模拟状态。
为什么用(1<<21):1<<21用二进制就是1000000…000(21个0),所以1<<21-1就有20个1。
我们可以用0表示还未使用此个数据。用1表示已经用过这个数据。

我们设置一个dp[1<<21],故转移就有
dp[ i | (1 << k) ] = max(dp[ i | ( 1 << k) ] ,dp[ i ]*a[ i ] + b[ i ] )
这里 ‘|’ 表示使用掉第k组数据,使二进制k位为1。
i 从 0遍历到(1<<21-1),即从一个都不取遍历到全取完的状态。

主要是这毒瘤的数据,用了java的BigInteger。c++的_int128也是可以的,文章最后有初版的c++代码。

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
    public static BigInteger[] a = new BigInteger[50];
    public static BigInteger[] b = new BigInteger[50];
    public static BigInteger[] dp = new BigInteger[1<<21];
    public static void main(String[] args) {
        BigInteger n,m;
        Scanner in = new Scanner(System.in);
        n = new BigInteger(in.next());
        m = new BigInteger(in.next());
        for (int i = 0;i < n.intValue();i++)
        {
            String s1,s2;
            s1 = in.next();
            s2 = in.next();
            a[i] = new BigInteger(s1);
            b[i] = new BigInteger(s2);
        }
        for (int i = 0;i < (1 << n.intValue());i++)
            dp[i] =new BigInteger("1");
        for (int i = 0; i < n.intValue(); i++) {
            dp[1 << i] = a[i].multiply(m).add(b[i]);
        }

        for (int i = 0; i < (1 << n.intValue()); i++) {
            for (int k = 0; k < n.intValue(); k++) {
                if (((i >> k) & 1) == 0) {
                    dp[i | (1 << k)] = dp[i | (1 << k)].max(dp[i].multiply(a[k]).add(b[k])) ;
                }
            }
        }
        System.out.println(dp[(1 << n.intValue()) - 1]);
    }
}

怕有些人还没学java,这里放一份没有改_int128的c++代码,可以自己动手改改

#include <bits/stdc++.h>

using namespace std;
//#define ACM_LOCAL
#define fi first
#define se second
#define il inline
#define re register
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int N = 2e5 + 10;
const int M = 1e6 + 10;
const int INF = 1e9 + 5;
const double eps = 1e-5;
const int MOD = 998244353;
ll a[N], b[N];
ll dp[1 << 21];

void solve() {
    ll n, m;
    cin >> n >> m;
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> b[i];
    }
    for (int i = 0; i < n; i++) dp[1 << i] = a[i] * m + b[i];
    for (int i = 0; i < (1 << n); i++) {
        for (int k = 0; k < n; k++) {
            if (!(i >> k & 1)) {
                dp[i | (1 << k)] = max(dp[i | (1 << k)], dp[i] * a[k] + b[k]);
            }
        }
    }
    cout << dp[(1 << n) - 1] << endl;
}

signed main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#ifdef ACM_LOCAL
    freopen("input", "r", stdin);
    freopen("output", "w", stdout);
#endif
    solve();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全评估测试题大模型安全评估测试题关键词库生成内容测试题库应拒答测试题库非拒答测试题大模型安全
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值