 /**//*
09年武漢賽的H題 help bubu
n本書,每本的高度在[25,32]
可以有m次抽出書的機會,然后再放回去
最后,高度相同的連續(xù)的書算一塊,求最少的塊

不會做,看下面這里的
http://hi.baidu.com/huicpc0328/blog/item/b6e32ef96708b202d9f9fd9f.html
Orz
高度只有8種
dp[i,j,mask,last] 表示前i本書,用了j次機會,未抽出的書高度為mask,最后一本的高度是last
它的值表示未抽出的書的塊數(shù)

轉(zhuǎn)移是枚舉第i本書,是抽走還是保留
抽走的話
dp[i,j+1,mask,last] = dp[i-1,j,mask,last]
保留的話
dp[i,j,mask|1<<h[i],h[i]] = dp[i-1,j,mask,last] + (last != h[i]) 如果跟last不同,就需要加塊數(shù)

我寫得比較遲鈍
初始化時,我多搞了一個高度,表示i=0時的高度,當然,這個高度跟其他書都不同
所以我的mask就9位了

在nankai可以過,1400ms吧
hdu過不了,只有1s
*/
#include<iostream>
#include<cstring>
#include<map>
#include<algorithm>
#include<stack>
#include<queue>
#include<cmath>
#include<string>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<set>
#include<list>
#include<numeric>
#include<cassert>
#include<ctime>

using namespace std;

const int INF = 1000000000;
const int LIMIT = 1<<9;

 inline int min(int a, int b) {
return a < b ? a : b;
}

int h[101];
int dp[2][101][LIMIT][9];//i,j,mask,last
int bitcount[LIMIT];

 int bitCount(int mask) {
int tot = 0;
 while( mask > 0) {
tot++;
mask -= mask & (-mask);//lowbit
}
return tot;
}

int main()
  {
#ifndef ONLINE_JUDGE
freopen("in","r",stdin);
#endif
 for (int mask = 0; mask < LIMIT ; mask++) {
bitcount[mask] = bitCount(mask);
}
 for (int n, m, t = 1; scanf("%d%d", &n, &m) , n ; ) {
int all = 256;
 for (int i = 1 ; i <= n ; i++) {
scanf("%d", &h[i]);
h[i] -= 25;
all |= 1<<h[i];
}
int now = 0 , pre = 1;
fill(dp[now][0][0], dp[now][m+1][0], INF);
dp[now][0][1<<8][8] = 0;
 for (int i = 1 ; i <= n ; i ++) {
swap(now, pre);
fill(dp[now][0][0], dp[now][m+1][0], INF);
 for (int j = 0, bound = min(m,i-1); j <= bound ; j ++) {
 for (int mask = 0; mask < LIMIT; mask ++) {
 for ( int last = 0 ; last < 9 ; last ++ ) {
 if( (mask & (1<<last) == 0) || dp[pre][j][mask][last] >= INF) {//
continue;
}
//take it
 if(j < m) {
dp[now][j+1][mask][last] = min(
dp[now][j+1][mask][last], dp[pre][j][mask][last]);
}
//keep it
dp[now][j][mask | (1<<h[i])][h[i]] = min(
dp[now][j][mask | (1<<h[i])][h[i]], dp[pre][j][mask][last] + (last != h[i])
);
}
}
}
}
int ans = INF;
 for (int j = 0; j <= m ; j++) {
 for (int mask = 0; mask < LIMIT ; mask++) {
 for (int last = 0; last < 9; last++) {
 if (dp[now][j][mask][last] < INF && (all & mask) == mask) {
ans = min(ans, dp[now][j][mask][last] + bitcount[all^mask]);//bitCount(all^mask));
}
}
}
}
printf("Case %d: %d\n\n", t++, ans);
}
return 0;
}
|
|
常用鏈接
隨筆分類
Links
搜索
最新評論

|
|