【bzoj4145】[AMPPZ2014]The Prices

状压背包
不太好说
很容易写

然而一开始写了个 O(n3m) 的T傻了没反应过来……

总之这个就是当前走到了第i个商店,购买状态是s,然后背包转移, O(nm2n)

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define per(i,a,b) for(int i=a;i>=b;i--)
#define For(i,a,b) for(int i=a;i< b;i++)
#define fors(s0,s) for(int s0=s;s0;s0=(s0-1)&s)
#define shl(i) (1 << (i))

inline int rd() {
 char c = getchar();
 while (!isdigit(c)) c = getchar() ; int x = c - '0';
 while (isdigit(c = getchar())) x = x * 10 + c - '0';
 return x;
}

inline void upmin(int&a , int b) { if (a > b) a = b ; }

int n , m , d[101] , c[101][16] , all , f[2][65536];

void input() {
 n = rd() , m = rd();
 For(i , 0 , n) {
 d[i] = rd();
 For(j , 0 , m) c[i][j] = rd();
 }
 all = shl(m);
}

void solve() {
 int now = 0 , pre = 1;
 memset(f , 0x3f , sizeof f);
 f[0][0] = 0;
 For(i , 0 , n) {
 now ^= 1 , pre ^= 1;
 For(s , 0 , all) f[now][s] = f[pre][s] + d[i];
 For(k , 0 , m) For(s , 0 , all) if (!(s & shl(k)))
 upmin(f[now][s | shl(k)] , f[now][s] + c[i][k]);
 For(s , 0 , all) upmin(f[now][s] , f[pre][s]);
 }
 printf("%d\n" , f[now][all - 1]);
}

int main() {
 input();
 solve();
 return 0;
}

你可能感兴趣的:(【bzoj4145】[AMPPZ2014]The Prices)