Bzoj 4145: [AMPPZ2014]The Prices

Bzoj 4145: [AMPPZ2014]The Prices

状态压缩dp

\(f[i][j]\)表示前i个商店 , 状态为j的最小花费.

考虑什么东西也不买和买了东西.

买了东西的话,就要到i地.

然后转移:\(f[i][j] = min(f[i][j] , f[i][j ^ (1 << k - 1)] + c[i][k])\)

不买东西

\(f[i][j] = f[i - 1][j]\)

/*header*/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <cmath>
#define rep(i , x, p) for(int i = x;i <= p;++ i)
#define sep(i , x, p) for(int i = x;i >= p;-- i)
#define gc getchar()
#define pc putchar
#define ll long long
#define mk make_pair
#define fi first
#define se second
using std::min;
using std::max;
using std::swap;

inline int gi() {
    int x = 0,f = 1;char c = gc;
    while(c < '0' || c > '9') {if(c == '-')f = -1;c = gc;}
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0';c = gc;}return x * f;
}

void print(int x) {
    if(x < 0) pc('-') , x = -x;
    if(x >= 10) print(x / 10);
    pc(x % 10 + '0');
}

const int maxN = 100 + 7;

void gmin(int &x , int y) {
    x = x > y ? y : x;
}

int f[maxN][65540] , c[maxN][maxN], d[maxN];

int main() {
    int n = gi() , m = gi();
    rep(i , 1, n) {
        d[i] = gi();
        rep(j , 1, m) c[i][j] = gi();
    }
    memset(f , 0x3f, sizeof(f));
    f[0][0] = 0;
    rep(i , 1, n) {
        rep(j , 0, (1 << m) - 1) f[i][j] = f[i - 1][j] + d[i];
        rep(j , 0, (1 << m) - 1) {
            rep(k , 1, m) {
                if(j & (1 << k - 1))
                    f[i][j] = min(f[i][j] , f[i][j ^ (1 << k - 1)] + c[i][k]);
            }
        }
        rep(j , 0, (1 << m) - 1) f[i][j] = min(f[i][j] , f[i - 1][j]);
    }
    printf("%d\n", f[n][(1 << m) - 1]);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gzygzy/p/10263060.html