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边”,如下图所示:

游戏规则如下:

  1. 从N块积木中选出若干块,并将它们分成M(l<=M<=N) 堆,称为第1堆,第2 堆…,第M堆。每堆至少有1块积木,并且第K堆中任意一块积木的编号要大于第K+1堆中任意一块积木的编号(2<=K<=M)。
  2. 对于每一堆积木,游戏者要将它们垂直摞成一根柱子,并要求满足下面两个条件:
    1. 除最顶上的一块积木外,任意一块积木的上表面同且仅同另一块积木的下表面接触,并且要求下面的积木的上表面能包含上面的积木的下表面,也就是说,要求下面的积木的上表面的两对边的长度分别大于等于上面的积木的两对边的长度。
    2. 对于任意两块上下表面相接触的积木,下面的积木的编号要小于上面的积木的编号。

最后,根据每人所摞成的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] 积木游戏的更多相关文章

  1. 动态规划(水题):COGS 261. [NOI1997] 积木游戏

    261. [NOI1997] 积木游戏 ★★   输入文件:buildinggame.in   输出文件:buildinggame.out   简单对比时间限制:1 s   内存限制:128 MB S ...

  2. [NOI1997] 积木游戏(dp)

    COGS 261. [NOI1997] 积木游戏 http://www.cogs.pro/cogs/problem/problem.php?pid=261 ★★   输入文件:buildinggame ...

  3. vijos 1464 NOIP 1997 积木游戏

    背景 1997年全国青少年信息学(计算机)奥林匹克竞赛试题 第二试 描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条 ...

  4. vijos 1464 积木游戏 DP

    描述 积木游戏 SERCOI 最近设计了一种积木游戏.每个游戏者有N块编号依次为1 ,2,…,N的长方体积木.对于每块积木,它的三条不同的边分别称为"a边"."b边&qu ...

  5. NOI 97 (Vijos 1464)积木游戏(DP)

    很普通的DP,设dp[i][j][k]为第i块积木放在第j堆且摆放状态为k的最高高度.方程很容易推出. # include <cstdio> # include <cstring&g ...

  6. Java实现蓝桥杯 算法提高 盾神与积木游戏

    题目描述 最近的m天盾神都去幼儿园陪小朋友们玩去了~ 每个小朋友都拿到了一些积木,他们各自需要不同数量的积木来拼一些他们想要的东西.但是有的小朋友拿得多,有的小朋友拿得少,有些小朋友需要拿到其他 小朋 ...

  7. noi 97 积木游戏

    思路:黑书的例题 #include<map> #include<set> #include<cmath> #include<queue> #includ ...

  8. Unity3D独立游戏开发日记(二):摆放建筑物

    在沙盒游戏里,能自由建造是很重要的特点,比如说风靡全球的<我的世界>,用一个个方块就能搭建出规模宏大的世界.甚至有偏激的人说,没有自由建造,就不是一个真正的沙盒游戏.的确,沙盒游戏的魅力有 ...

  9. 【转】ACM训练计划

    [转] POJ推荐50题以及ACM训练方案 -- : 转载自 wade_wang 最终编辑 000lzl POJ 推荐50题 第一类 动态规划(至少6题, 和 必做) 和 (可贪心) (稍难) 第二类 ...

随机推荐

  1. 超实用 1 ArrayList 链表

    package ArrayList链表; import java.util.*; public class kk1 { /** * 作者:Mr.Fan * 功能:记住ArrayList链表 */ pu ...

  2. cobbler技术详解(是PXE二次详解)

    Cobbler是PXE的二次封装,使用Python语言开发, 可以用来快速建立 Linux 网络安装环境,它已将 Linux 网络安装的技术门槛,从大专以上文化水平,成功降低到初中以下,连补鞋匠都能学 ...

  3. Beta阶段冲刺前的准备

    Beta阶段冲刺前的准备 凡事预则立,在Beta开始前,以小组为单位,在敏捷冲刺前发布一篇博客,描述: 1. 讨论组长是否重选的议题和结论 经过我们小组在周二下午的会议中有重新认真的考虑了是否要更换组 ...

  4. Beta阶段冲刺前准备

    第 1 篇 Scrum 冲刺博客 1.新成员 暂无新成员,等一个有缘人 团队成员: 刘阳航(captain) 陈文俊 林庭亦 郑子熙 2.讨论是否需要更换团队的PM 经过团队讨论,我们决定不更换团队P ...

  5. Mysql Group Replication 简介及单主模式组复制配置【转】

    一 Mysql Group Replication简介    Mysql Group Replication(MGR)是一个全新的高可用和高扩张的MySQL集群服务.    高一致性,基于原生复制及p ...

  6. Delphi中比较两个对象是否一致及地址是否相同[转]

    在delphi中,C#也是如此,对象的地址与对象变量(引用)的地址不是同一个概念.要加以区别. procedure TForm1.btn1Click(Sender: TObject); var    ...

  7. Cannot open the disk 'D:\win7-ie8\Windows 7 x64.vmdk' or one of the snapshot

    使用机子过程中断电,开机后使用虚拟机提示[Cannot open the disk 'D:\win7-ie8\Windows 7 x64.vmdk' or one of the snapshot],找 ...

  8. Windows 常见错误总结

    本篇主要记录Windows 系统使用中存在的问题和解决方案,会保持持续更新...(若你们遇到的问题或有更好的解决方法,还望在评论区留言,谢谢) 1.win10 unable to save C:\wi ...

  9. java 表单验证

    java 表单验证 1.思路:通过表单选择器,表单属性过滤器提取每个表单提交的值,进行验证 2.实现:javascript通过 onSubmit()事件,判断,返回值false不提交,返回true提交 ...

  10. AtCoder Grand Contest 005

    AtCoder Grand Contest 005 A - STring 翻译 给定一个只包含\(ST\)的字符串,如果出现了连续的\(ST\),就把他删去,然后所有位置前移.问最后剩下的串长. 题解 ...