/**//* 09年武汉赛的H题 help bubu n本书,每本的高度在[25,32] 可以有m次抽出书的机会,然后再放回去 最后,高度相同的连续的书算一块,求最少的块
不会做,看下面这里的 http://hi.baidu.com/huicpc0328/blog/item/b6e32ef96708b202d9f9fd9f.html Orz 高度只有8种 dp[i,j,mask,last] 表示前i本书,用了j次机会,未抽出的书高度为mask,最后一本的高度是last 它的值表示未抽出的书的块数
转移是枚举第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不同,就需要加块数
我写得比较迟钝 初始化时,我多搞了一个高度,表示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
搜索
最新评论
|
|