AcWing - 165 - 小猫爬山 = 状压dp

时间:2019-10-07
本文章向大家介绍AcWing - 165 - 小猫爬山 = 状压dp,主要包括AcWing - 165 - 小猫爬山 = 状压dp使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://www.acwing.com/problem/content/167/

18只猫,每只猫有重量,车有载重上限,求最小的数量的车把猫装完,保证有解。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int INF = 0x3f3f3f3f;
//dp[i][j]表示用了i只猫,j辆缆车,最后一辆缆车的最大空间
int dp[1 << 18][19];
int a[18];

int main() {
#ifdef Yinku
    freopen("Yinku.in", "r", stdin);
#endif // Yinku
    int n, w;
    scanf("%d%d", &n, &w);
    for(int i = 0; i < n; ++i)
        scanf("%d", &a[i]);
    memset(dp, -INF, sizeof(dp));
    for(int k = 1; k <= n; ++k) {
        dp[0][k] = w;
    }
    for(int i = 0; i < (1 << n); ++i) {
        for(int j = 0; j < n; ++j) {
            if((i & (1 << j)) == 0) {
                for(int k = 0; k <= n; ++k) {
                    if(dp[i][k] >= a[j]) {
                        dp[i | (1 << j)][k] = max(dp[i | (1 << j)][k], dp[i][k] - a[j]);
                    }
                    if(dp[i][k] >= 0 && k + 1 <= n)
                        dp[i | (1 << j)][k + 1] = max(dp[i | (1 << j)][k + 1], w - a[j]);
                }
            }
        }
        /*for(int k = 0; k <= n; ++k) {
            printf("dp[");
            cout << bitset<5>(i);
            printf("][%d]=%d\n", k, dp[i][k]);
        }
        puts("");*/
    }

    for(int k = 0; k <= n; ++k) {
        if(dp[(1 << n) - 1][k] >= 0) {
            printf("%d\n", k);
            return 0;
        }
    }
}

原文地址:https://www.cnblogs.com/Inko/p/11631110.html