ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

UVA12235 Help Bubu 题解

2021-12-06 22:04:20  阅读:169  来源: 互联网

标签:Bubu 本书 ch Help mess 题解 31 32


题目链接

题目

Bubu’s bookshelf is in a mess! Help him!
There are nbooks on his bookshelf. We define the mess value to be the number of segments of
consecutive equal-height books. For example, if the book heights are 30, 30, 31, 31, 32, the mess
value is 3, that of 30, 32, 32, 31 is also 3, but the mess value of 31, 32, 31, 32, 31 is 5 — it’s indeed in
a mess!
Bubu wants to reduce the mess value as much as possible, but he’s a little bit tired, so he decided
to take out at most kbooks, then put them back somewhere in the shelf. Could you help him?

书架上有 N 本书,书本高度是 [25cm,32cm],凌乱地排着。
定义一排书的整齐度是指最少可以被划分成高度连续相等的书的段数
比如 {30,32,32,31} 整齐度是 3。
比如 {31,32,31,32,31} 整齐度是 5。
现在最多从其中拿出 K 本书,然后塞回去。
问整理后,最少可以有多少段高度相等的连续区间。

K <= N <= 100

思路

发现书本高度最大最小差为8,很容易想到状压dp。

设 \(dp(i, j, k, o)\) 表示前 \(i\) 本书里拿出 \(j\) 本,剩下书高度集合为 \(k\),且最后一本书高度为 \(o\) 的最小凌乱度。

然后枚举每一本书拿或者不拿。

如果不拿,则 \(k\) 变成 \(k|(1<<a_i)\),代表这本书放入未被拿的集合。\(o\) 变成 \(a_i\)。如果之前 \(o\neq a_i\),则要加1。

如果拿,剩下书的集合还有最后一本不变。然后我们考虑是否+1,如果为拿出的集合中有这本书,我们可以把现在这本书插到它旁边,然后不用+1。如果后面还有和它一样的书,我们就把现在这本书的命运交给后面那本书。除了这两种情况,其它都要+1。

可能会MLE,要滚动数组优化。

Code

// Problem: UVA12235 Help Bubu
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/UVA12235
// Memory Limit: 0 MB
// Time Limit: 3000 ms
// 
// Powered by CP Editor (https://cpeditor.org)

#include<bits/stdc++.h>
using namespace std;
//#define int long long
inline int read(){int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;
ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+
(x<<3)+(ch^48);ch=getchar();}return x*f;}
//#define M
//#define mo
#define N 110
int n, m, i, j, k; 
int ans, dp[2][N][300][10]; 
int is[1010][10], a[1010]; 
int o, nw, ls, K, t; 

void minn(int &x, int y)
{
	x=min(x, y); 
}

signed main()
{
//	freopen("tiaoshi.in", "r", stdin); 
//	freopen("tiaoshi.out", "w", stdout); 
	scanf("%d%d", &n, &K);
	while(n)
	{
		memset(dp, 0x3f, sizeof(dp)); 
		memset(is, 0, sizeof(is)); 
		for(i=1; i<=n; ++i) a[i]=read()-25; 
		// for(i=1; i<=n; ++i) printf("%d ", a[i]);  
		// printf("\n"); 
		for(i=1; i<=n; ++i)
			for(j=i+1; j<=n; ++j)
				is[i][a[j]]=1; 
		ans=dp[0][0][0][0]; 
		dp[0][0][0][8]=0; 
		for(i=1; i<=n; ++i)
		{
			nw=i&1; ls=(!nw); 
			memset(dp[nw], 0x3f, sizeof(dp[nw])); 
			for(j=0; j<=K; ++j)
				for(k=0; k<=255; ++k)
					for(o=0; o<=8; ++o)
						if(o==8||((1<<o)&k))//之前未选集合中含有最后一个
						{
							minn(dp[nw][j][k|(1<<a[i])][a[i]], dp[ls][j][k][o]+(a[i]!=o)); 
							if(j) minn(dp[nw][j][k][o], dp[ls][j-1][k][o]+( (((1<<a[i])&k)||(is[i][a[i]])) ? 0 : 1 ) ); 
						}
		}
		for(j=0; j<=K; ++j)
			for(k=0; k<=255; ++k)
				for(o=0; o<=8; ++o)
					if(o==8||((1<<o)&k)) 
						ans=min(ans, dp[n&1][j][k][o]); 
		printf("Case %d: %d\n\n", ++t, ans); 
		scanf("%d%d", &n, &K);
	}
	return 0; 
}

标签:Bubu,本书,ch,Help,mess,题解,31,32
来源: https://www.cnblogs.com/zhangtingxi/p/15652046.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有