为什么这个谱子上加一间是do啊(&#sld3237vf;_&#sld3237vf;)迷茫

亿万蜜婚:神秘墨少甜娇妻_第240章 去了H&;T集团_云起书院目录作品相关第一卷 [免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费][免费]第一卷 VIP卷订阅自动订阅简单订阅1252人阅读
全部博客(230)
ACM_动态规划(DP)(98)
题目链接:
题目大意:一个书架有n本书,每本书的高度介于25和32之间,n本书中高度连续相同的算一段,一般来说n本书会有很多段,现在可以取出k本书再插进原书架中,问这些书最少有几段?n
解题思路:由于书的高度介于25和32之间,可以把书的高度减去25变成介于0和7之间,这个数字就很适合状态压缩了。思考的时候就尽量往高度进行压缩。每本书有两种选择,一种留下,一种抽走,留下的书和抽走的书可以用两个状态表示,如果抽出去的书不在留下的书里面,那么最后就要增加一段。每本书似乎只和留下来的最后一本书的状态有关,如果书的高度和留下的最后一本书的高度相同,那么可以直接合并进去而不必计算高度,如果不相同则要增加段数。
& & 那我们要怎么表示抽走的状态呢?压缩成一个数字吗?不行,还必须和k扯上关系,也就是说必须有一维表示数量,而抽走书的种类可以用总状态减去留下来的状态来表示。这样就可以用dp[i][j][k][s]来进行状态转移,dp[i][j][k][s]表示到第i本书时取走j本书留下来的书状态为k最后一本书高度为s。状态转移见代码。复杂度O(n*k*(1&&8)*8)。
测试数据:
25 25 32 32 25
25 26 25 26 25
代码#include &stdio.h&
#include &string.h&
#define MIN 110
#define INF
#define min(a,b) (a)&(b)?(a):(b)
int n,m,ht[MIN],ans,one[1&&8]; //one[i]表示状态i中1的个数
int state,dp[2][MIN][1&&8][10];//dp[i][j][k][s]表示到第i行取走j本书剩下的状态数为k最后一本书高度是s时最少连续段数
void Initial() {
for (int i = 0; i & (1&&8); ++i) {
for (int j = 0; j & 8; ++j)
if (i & (1&&j)) one[i]++;
int main()
int i,j,k,s,cas = 0;
int pre,cur,mx,
Initial();
while (scanf(&%d%d&,&n,&m) ,n+m) {
mx = state = 0;
for (i = 1; i &= ++i) {
scanf(&%d&,&ht[i]);
ht[i] -= 25;
if (ht[i] & mx) mx = ht[i];
//统计最大的高度
state |= (1&&ht[i]);
mx++ ,tot = (1&&mx);
for (j = 0; j &= ++j)
for (k = 0; k & ++k)
for (s = 0; s &= ++s)
dp[1][j][k][s] = INF;
dp[1][0][1&&ht[1]][ht[1]] = 1;
//如果第一本书留下来段数就为1
dp[1][1][0][mx] = 0;
//mx其实是不存在的高度,因为第一本书被拿走了那么留下的最后一本书高度实际是不存在的,用这个只是好转移
for (i = 2; i &= ++i) {
cur = i & 1;
//当前状态
//前一个状态
for (j = 0; j &= ++j)
for (k = 0; k & ++k)
for (s = 0; s &= ++s)
dp[cur][j][k][s] = INF;
for (j = 0; j &= m && j & ++j)
for (k = 0; k & ++k)
for (s = 0; s &= ++s) {
if (dp[pre][j][k][s] == INF)
//小剪枝,但不剪就TLE
int stk = k | (1&&ht[i]);
//当前的状态
if (j & m)
//如果还可以取走
dp[cur][j + 1][k][s] = min(dp[cur][j + 1][k][s], dp[pre][j][k][s]);
if (s == ht[i])
//如果和留下来的最后一本高度相同,则当前的书留下来并不增加段数
dp[cur][j][k][s] = min(dp[cur][j][k][s],dp[pre][j][k][s]);
//增加一段
dp[cur][j][stk][ht[i]] = min(dp[cur][j][stk][ht[i]],dp[pre][j][k][s]+1);
cur = n & 1,ans =
for (j = 0; j &= ++j)
for (k = 0; k & ++k)
for (s = 0; s & ++s)
if (dp[cur][j][k][s] != INF) {
int st = state ^
ans = min(ans,one[st]+dp[cur][j][k][s]);
printf(&Case %d: %d\n\n&,++cas,ans);
本文ZeroClock原创,但可以转载,因为我们是兄弟。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:393234次
积分:6699
积分:6699
排名:第2585名
原创:231篇
评论:420条
(1)(5)(4)(4)(9)(22)(21)(37)(27)(71)(32)}

我要回帖

更多关于 9.6.5.3237 注册码 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信