一开始没看懂题解,后来想明白以后,d(i, j, s, x)是考虑第i本书的时候,前面已经拿走了j本书,剩下的书的种类的二进制状态为s,剩下的最后一本书的编号为x,所能得到的最小混乱度。
这里状态定义的时候,先不考虑把拿出来的书放回去。
最后统计答案的时候,把那些拿出来的书再加上。
all是所有n本书的状态,s是剩下书的种类的状态。
如果拿出来的书中有和前面高度相同的,直接插到相邻的位置就行了,不会增加混乱度。
如果拿出来的书中没有和前面高度相同的,不管放在那里混乱度都会加1,这样所增加的混乱度就是bitcount(all ^ s)
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 using namespace std; 5 6 const int maxn = 100 + 5; 7 const int maxs = (1 << 8); 8 const int INF = 0x3f3f3f3f; 9 10 int n, k; 11 12 int a[maxn]; 13 int d[2][maxn][maxs][8]; 14 15 int bitcount(int x) 16 { 17 int ans = 0; 18 while(x) { ans += (x&1); x >>= 1; } 19 return ans; 20 } 21 22 int main() 23 { 24 int kase = 0; 25 26 while(scanf("%d%d", &n, &k) == 2) 27 { 28 if(!n && !k) break; 29 30 for(int i = 0; i < n; i++) scanf("%d", a + i); 31 32 memset(d[0], 0x3f, sizeof(d[0])); 33 int cur = 0; 34 int all = 0; 35 36 for(int i = 0; i < n; i++) 37 { 38 cur ^= 1; 39 memset(d[cur], 0x3f, sizeof(d[cur])); 40 int h = a[i] - 25; 41 d[cur][i][1<<h][h] = 1; 42 43 for(int j = 0; j <= min(k, i); j++) 44 for(int s = all; s; s = (s-1)&all) 45 for(int x = 0; (1 << x) <= s; x++) 46 if(d[cur^1][j][s][x] != INF) 47 { 48 int t = d[cur^1][j][s][x]; 49 if(x == h) d[cur][j][s][x] = min(d[cur][j][s][x], t); 50 else 51 { 52 d[cur][j+1][s][x] = min(d[cur][j+1][s][x], t); 53 d[cur][j][s|(1<<h)][h] = min(d[cur][j][s|(1<<h)][h], t + 1); 54 } 55 } 56 all |= (1 << h); 57 } 58 59 int ans = n; 60 for(int j = 0; j <= k; j++) 61 for(int s = all; s; s = (s-1)&all) 62 for(int x = 0; (1 << x) <= s; x++) 63 ans = min(ans, d[cur][j][s][x] + bitcount(all^s)); 64 printf("Case %d: %d\n\n", ++kase, ans); 65 } 66 67 return 0; 68 }
代码君
时间: 2024-09-30 16:51:10