[NOI1997] 积木游戏
COGS 261. [NOI1997] 积木游戏
http://www.cogs.pro/cogs/problem/problem.php?pid=261
★★ 输入文件:buildinggame.in 输出文件:buildinggame.out 简单对比
时间限制:1 s 内存限制:128 MB

SERCOI 最近设计了一种积木游戏。每个游戏者有N块编号依次为1 ,2,…,N的长方体积木。对于每块积木,它的三条不同的边分别称为”a边”、“b边”和”c边”,如下图所示:
游戏规则如下:
- 从N块积木中选出若干块,并将它们分成M(l<=M<=N) 堆,称为第1堆,第2 堆…,第M堆。每堆至少有1块积木,并且第K堆中任意一块积木的编号要大于第K+1堆中任意一块积木的编号(2<=K<=M)。
- 对于每一堆积木,游戏者要将它们垂直摞成一根柱子,并要求满足下面两个条件:
- 除最顶上的一块积木外,任意一块积木的上表面同且仅同另一块积木的下表面接触,并且要求下面的积木的上表面能包含上面的积木的下表面,也就是说,要求下面的积木的上表面的两对边的长度分别大于等于上面的积木的两对边的长度。
- 对于任意两块上下表面相接触的积木,下面的积木的编号要小于上面的积木的编号。
最后,根据每人所摞成的M根柱子的高度之和来决出胜负。
请你编一程序,寻找一种摞积木的方案,使得你所摞成的M根柱子的高度之和最大。
输入输出
输入文件的第一行有两个正整数N和M(1<=M<=N<=100),分别表示积木总数和要求 摞成的柱子数。这两个数之间用一个空格符隔开。接下来N行依次是编号从1到N的N个积木的尺寸,每行有三个1至1000之间的整数,分别表示该积木a 边,b边和c边的长度。同一行相邻两个数之间用一个空格符隔开。
输出文件只有一行,为一个整数,表示M根柱子的高度之和。
样例
输入文件
4 2
10 5 5
8 7 7
2 2 2
6 6 6
输出文件
24
f[k][i][j][l] 表示 前i个积木分为k组,第k组最后一个是j,j的摆放方式为l的最大高度
对于每一个积木有3种决策:
① 与前面积木合为一组 f[k][i][i][l]=max(f[k][i][j][t])+high[i]
② 自己另放一组 f[k][i][i][l]=max(f[k-1][i-1][j][t])+high[i]
③ 不放 f[k][i][j][l]=f[k][i-1][j][l]
其中0<=j<i 0<=t<=2 表示3种放置方式
ans=max(f[m][n][i][j]) 1<=i<=n,0<=j<=2
为了方便比较大小关系,我们可以先对输入每块积木的a,b,c排序,这样在DP中就不用判断同一块积木的长宽高
代码中的一些细节:
排序方式,每块积木最小的参数为a,中间的是b,最大的为c
状态表示方法:
0 表示 ab面为底;1 表示 ac面为底; 2表示bc面为底
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,a[],b[],c[],f[][][][];
int main()
{
/*freopen("buildinggame.in","r",stdin);
freopen("buildinggame.out","w",stdout);*/
scanf("%d%d",&n,&m);
for(int i=;i<=n;i++)
{
scanf("%d%d%d",&a[i],&b[i],&c[i]);
if(a[i]>b[i]) swap(a[i],b[i]);
if(b[i]>c[i]) swap(b[i],c[i]);
if(a[i]>b[i]) swap(a[i],b[i]);
}
for(int k=;k<=m;k++)
for(int i=;i<=n;i++)
for(int j=;j<i;j++)
for(int l=;l<=;l++)
{
int aa,bb,cc;
if(l==) aa=a[i],bb=b[i],cc=c[i];
else if(l==) aa=a[i],bb=c[i],cc=b[i];
else aa=b[i],bb=c[i],cc=a[i];
if(aa<=a[j]&&bb<=b[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-][j][]+cc);
if(aa<=a[j]&&bb<=c[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-][j][]+cc);
if(aa<=b[j]&&bb<=c[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-][j][]+cc);
f[k][i][i][l]=max(f[k][i][i][l],f[k-][i-][j][]+cc);
f[k][i][i][l]=max(f[k][i][i][l],f[k-][i-][j][]+cc);
f[k][i][i][l]=max(f[k][i][i][l],f[k-][i-][j][]+cc);
f[k][i][j][l]=f[k][i-][j][l];
}
int ans=;
for(int i=;i<=n;i++)
for(int j=;j<=;j++)
ans=max(ans,f[m][n][i][j]);
printf("%d",ans);
}
2个错误:
1、j没有从0开始,从1开始,导致f[1][1][1][]的状态没有统计
2、转移中a,b,c交换错误,错误原因还没有找出
if(l==1) swap(b[i],c[i]);
else if(l==2) {swap(a[i],b[i]);swap(a[i],c[i]);}
if(a[i]<=a[j]&&b[i]<=b[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-1][j][0]+c[i]);
if(a[i]<=a[j]&&b[i]<=c[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-1][j][1]+c[i]);
if(a[i]<=b[j]&&b[i]<=c[j]) f[k][i][i][l]=max(f[k][i][i][l],f[k][i-1][j][2]+c[i]);
f[k][i][i][l]=max(f[k][i][i][l],f[k-1][i-1][j][0]+c[i]);
f[k][i][i][l]=max(f[k][i][i][l],f[k-1][i-1][j][1]+c[i]);
f[k][i][i][l]=max(f[k][i][i][l],f[k-1][i-1][j][2]+c[i]);
f[k][i][j][l]=f[k][i-1][j][l];
if(l==1) swap(b[i],c[i]);
else if(l==2) {swap(a[i],b[i]);swap(a[i],c[i]);}
错误代码
[NOI1997] 积木游戏的更多相关文章
- 动态规划(水题):COGS 261. [NOI1997] 积木游戏
261. [NOI1997] 积木游戏 ★★ 输入文件:buildinggame.in 输出文件:buildinggame.out 简单对比时间限制:1 s 内存限制:128 MB S ...
- [NOI1997] 积木游戏(dp)
COGS 261. [NOI1997] 积木游戏 http://www.cogs.pro/cogs/problem/problem.php?pid=261 ★★ 输入文件:buildinggame ...
- vijos 1464 NOIP 1997 积木游戏
背景 1997年全国青少年信息学(计算机)奥林匹克竞赛试题 第二试 描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条 ...
- vijos 1464 积木游戏 DP
描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条不同的边分别称为"a边"."b边&qu ...
- NOI 97 (Vijos 1464)积木游戏(DP)
很普通的DP,设dp[i][j][k]为第i块积木放在第j堆且摆放状态为k的最高高度.方程很容易推出. # include <cstdio> # include <cstring&g ...
- Java实现蓝桥杯 算法提高 盾神与积木游戏
题目描述 最近的m天盾神都去幼儿园陪小朋友们玩去了~ 每个小朋友都拿到了一些积木,他们各自需要不同数量的积木来拼一些他们想要的东西.但是有的小朋友拿得多,有的小朋友拿得少,有些小朋友需要拿到其他 小朋 ...
- noi 97 积木游戏
思路:黑书的例题 #include<map> #include<set> #include<cmath> #include<queue> #includ ...
- Unity3D独立游戏开发日记(二):摆放建筑物
在沙盒游戏里,能自由建造是很重要的特点,比如说风靡全球的<我的世界>,用一个个方块就能搭建出规模宏大的世界.甚至有偏激的人说,没有自由建造,就不是一个真正的沙盒游戏.的确,沙盒游戏的魅力有 ...
- 【转】ACM训练计划
[转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...
随机推荐
- Alpha版本冲刺(六)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:翟丹丹 组员7:何家伟 组员8:政演 组员9:黄鸿杰 组员10:刘一好 组员11:何宇恒 展示 ...
- lintcode-513-完美平方
513-完美平方 给一个正整数 n, 找到若干个完全平方数(比如1, 4, 9, ... )使得他们的和等于 n.你需要让平方数的个数最少. 样例 给出 n = 12, 返回 3 因为 12 = 4 ...
- 交换机、linux光衰查询
RX收光,TX发光 一.交换机 命令: display interface transceiver brief 结果: ...... HW6851 10GE1/0/15 transceiver dia ...
- JS获取地址栏中的链接URL参数
function getUrlParam(name){ var reg = new RegExp("(^|&)"+ name +"=([^&]*)(&am ...
- display:flex 布局教程,弹性布局!
display:flex 布局教程 布局的传统解决方案,基于盒状模型,依赖 display属性 + position属性 + float属性.它对于那些特殊布局非常不方便,比如,垂直居中就不容易实现. ...
- [转帖]中国SaaS死或生之一:“网红”CRM的大起大落
中国SaaS死或生之一:“网红”CRM的大起大落 http://www.cniteyes.com/archives/33709 文章摘要:从“大众情人”到被人遗弃,如何从CRM身上审视中国Sa ...
- 实现LinearLayout(垂直布局,Gravity内容排布)
首先上Gravity的代码,Android原版的Gravity搞得挺复杂的,太高端了.但基本思路是使用位运算来做常量,我就自己消化了一些,按自己的思路来实现. 先上代码,在做分析. package k ...
- sql学习. case + group by 都干了啥子事情
select case pref_name when 'fudao' then 'siguo' when 'xiangchuan' then 'siguo' when 'aiyuan' then 's ...
- poj3320 Jessica's Reading Problem
Description Jessica's a very lovely girl wooed by lots of boys. Recently she has a problem. The fina ...
- MySQL复制 -- 复制出错怎么办?
假如我们生产环境复制出错?该怎么办呢? 下面提供几种办法: 1. 手工处理,补回不一致数据(可以利用主库来补数据.也可以利用binlog来补数据) 2.用开源工具来解决一致性问题 3.自己造轮子,解决 ...