1. 程式人生 > >[luoguP3052] [USACO12MAR]摩天大樓裏的奶牛Cows in a Skyscraper(DP)

[luoguP3052] [USACO12MAR]摩天大樓裏的奶牛Cows in a Skyscraper(DP)

摩天大樓 close 技術 printf opera col cli 裏的 pen

傳送門

輸出被閹割了。

只輸出最少分的組數即可。

f 數組為結構體

f[S].cnt 表示集合 S 最少的分組數

f[S].v  表示集合 S 最少分組數下當前組所用的最少容量

f[S] = min(f[S], f[S - i] + a[i]) (i ∈ S)

運算重載一下即可。

——代碼

技術分享
 1 #include <cstdio>
 2 #include <iostream>
 3 
 4 int n, m, w;
 5 int a[19];
 6 struct qwq
 7 {
 8
int cnt, v; 9 qwq(int cnt = 0, int v = 0) : cnt(cnt), v(v) {} 10 }f[1 << 19]; 11 12 inline qwq operator + (const qwq x, const int d) 13 { 14 return x.v + d <= w ? qwq(x.cnt, x.v + d) : qwq(x.cnt + 1, d); 15 } 16 17 inline bool operator < (const qwq x, const qwq y)
18 { 19 return x.cnt == y.cnt ? x.v < y.v : x.cnt < y.cnt; 20 } 21 22 inline qwq min(qwq x, qwq y) 23 { 24 return x < y ? x : y; 25 } 26 27 inline int read() 28 { 29 int x = 0, f = 1; 30 char ch = getchar(); 31 for(; !isdigit(ch); ch = getchar()) if(ch == -
) f = -1; 32 for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - 0; 33 return x * f; 34 } 35 36 int main() 37 { 38 int i, S; 39 n = read(); 40 w = read(); 41 m = (1 << n) - 1; 42 for(i = 1; i <= n; i++) a[i] = read(); 43 for(S = 1; S <= m; S++) 44 { 45 f[S] = qwq(1e9, w); 46 for(i = 1; i <= n; i++) 47 { 48 if(!((1 << i - 1) & S)) continue; 49 f[S] = min(f[S], f[(1 << i - 1) ^ S] + a[i]); 50 } 51 } 52 printf("%d\n", f[m].cnt + 1); 53 return 0; 54 }
View Code

[luoguP3052] [USACO12MAR]摩天大樓裏的奶牛Cows in a Skyscraper(DP)