zoukankan      html  css  js  c++  java
  • 【状压dp】AC Challenge

    https://nanti.jisuanke.com/t/30994

    把每道题的前置条件用二进制压缩,然后dp枚举所有可能状态,再枚举该状态是从哪一个节点转移来的,符合前置条件则更新。

    代码:

    #include <iostream>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    typedef long long ll;
    const int maxn = 1 << 20;
    ll dp[maxn], a[21], b[21];
    int pre[21];
    int calc(int s) {
    	int res = 0;
    	for (int i = 0; i < 20; i++) {
    		if ((1 << i) & s) {
    			res++;
    		}
    	}
    	return res;
    }
    int main() {
    	int n;
    	memset(dp, -0x3f, sizeof dp);
    	scanf("%d", &n);
    	for (int i = 1, t, x; i <= n; i++) {
    		scanf("%lld%lld%d", &a[i], &b[i], &t);
    		while (t--) {
    			scanf("%d", &x);
    			pre[i] += (1 << (x - 1));
    		}
    	}
    	ll ans = 0;
    	dp[0] = 0;
    	for (int i = 1; i < (1 << n); i++) {
    		for (int j = 0; j < n; j++) {
    			if (i & (1 << j)) {
    				int t = i - (1 << j);
    				if ((t & pre[j + 1]) == pre[j + 1]) {
    					dp[i] = max(dp[i], dp[t] + calc(i) * a[j + 1] + b[j + 1]);
    					ans = max(ans, dp[i]);
    				}
    			}
    		}
    	}
    	printf("%lld
    ", ans);
    }
  • 相关阅读:
    引用的难点:函数返回值是引用(引用当左值)
    引用的意义与本质
    引用做函数参数
    Uva
    Uva
    Uva
    暑假集训-8.06总结
    暑假集训-8.05总结
    CH1801( 括号画家)
    最大异或对
  • 原文地址:https://www.cnblogs.com/stolf/p/9572209.html
Copyright © 2011-2022 走看看