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. Java中的常见异常

    非检查异常:Error 和 RuntimeException 以及他们的子类.0错误ArithmeticException,错误的强制类型转换错误ClassCastException,数组索引越界Ar ...

  2. vue 过渡效果

    Vue中提供了`<transition>`和`<transition-group>`来为元素增加过渡动画.文档写的很清楚,但是实际使用起来还是费了一番功夫.这里做一个简单的记录 ...

  3. strtr、str_replace()、substr_replace、preg_replace之间的区别

    strtr(string, from, to): 逐个字符开始替换,以from跟to中长度较较短的一个为准,例如: strtr("aidengni","ai", ...

  4. Js 中的原始值和引用值

    最近遇写 node.js 时到一个问题,把对象当赋值给数组成员时总是出错,比如下面的代码, var Arr = new Array(); var Obj = new Object(); for(var ...

  5. Qt Lighthouse学习(二),就是QPA(Qt Platform Abstraction) 项目的名字

    上一次关注Qt Lighthouse是在6月初,可是现在都8月底了.时间真快... Lighthouse 是 QPA(Qt Platform Abstraction) 项目的名字,它使得将Qt移植到新 ...

  6. 1使用 vue-cli 搭建项目(cp)

    http://www.cnblogs.com/wisewrong/p/6255817.html(copy:web) https://zhuanlan.zhihu.com/p/26183652(也很好) ...

  7. javascript定时保存表单数据的代码

    (忘记是不是两家邮箱都有这个功能). 那这个功能是怎么做的呢? 定时,我们知道怎么弄,但保存呢?也许我们会通过隐藏域等手段来存放数据.但是,这个却有个缺点:那就是刷新页面后,数据将会丢失. 而此时,就 ...

  8. poj3061 Subsequence(尺取)

    Description A sequence of N positive integers (10 < N < 100 000), each of them less than or eq ...

  9. 【BZOJ2006】【NOI2010】超级钢琴(主席树,优先队列)

    [BZOJ2006]超级钢琴(主席树,优先队列) 题面 BZOJ 题解 既然是一段区间 首先就要变成单点 所以求一个前缀和 这个时候贪心很明显了: 枚举每一个点和可以和它组成一段的可行的点 全部丢进一 ...

  10. android与H5互相调用

    市面上很多android软件都有内嵌H5的,主要是为了节约成本,提高开发效率,其实现原理主要是通过Java代码和JavaScript代码的互相调用来实现. Java调用Js 1,webview初始化: ...