博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[NOI 1997] 积木游戏(dp)
阅读量:5208 次
发布时间:2019-06-14

本文共 2149 字,大约阅读时间需要 7 分钟。

·题目描述

一种积木游戏,游戏者有N块编号依次为1,2,…,N的长方体积木。第I块积木通过同一顶点三条边的长度分别为ai,bi,ci(i=1,2,…,N),如图1所示:

o_o_1.jpg

游戏规则如下:

1 从N块积木中选出若干块,并将他们摞成M(1<= M <= N)根柱子,编号依次为1,2,…,M,要求第k根柱子的任意一块积木的编号都必须大于第K-1根柱子任意一块积木的编号(2<=K<=M)。

2 对于每一根柱子,一定要满足下面三个条件:

除最顶上的一块积木外,任意一块积木的上表面同且仅同另一块积木的下表面接触;

对于任意两块上下表面相接触的积木,若m,n是下面一块积木接触面的两条边(m>=n),x,y是上面一块积木接触面的两条边(x>=y),则一定满足m.>=x和n>=y;

下面的积木的编号要小于上面的积木的编号。

请你编一程序,寻找一种游戏方案,使得所有能摞成的M根柱子的高度之和最大。

·输入格式

文件的第一行是两个正整数N和M(1<= M <= N <=100),分别表示积木总数和要求摞成的柱子数。这两个数之间用一个空格符隔开。接下来的N行是编号从1到N个积木的尺寸,每行有三个1至500之间的整数,分别表示该积木三条边的长度。同一行相邻两个数之间用一个空格符隔开。

·输出格式

文件只有一行,是一个整数,表示所求得的游戏方案中M根柱子的高度之和。

·样例输入

4 2

10 5 5
8 7 7
2 2 2
6 6 6

·样例输出

24

题解:

拿到这题,考虑了一下写记忆化搜索,dfs(int id,int bottom,int k),\(id\)表示当前考虑的积木,\(bottom\)表示该积木下的积木序号,\(k\)表示当前考虑第\(id\)块积木的第\(k\)面。感觉可以瞎搞搞,但是由于我太懒就没有继续想下去。。。(ε=ε=ε=┏(゜ロ゜;)┛逃)

后来看到这题出处,97年NOI的dp题,应该值得一写,于是重新思考了一下。

我们用\(f[i][j][k]\)表示当前在搭第i根柱子,考虑第\(j\)个积木的第\(k\)面。于是,每个积木都有\(3\)个决策,要么放在上一个积木的上面(有条件约束),要么去搭下一根柱子,要么不用它。所以,我们很容易就可以写出状态转移方程。

详情见代码。。。(,,ԾㅂԾ,,)

#include 
#include
#include
#define Re register intusing namespace std;int N,M,x1,y1,x2,y2,d[105][3],f[105][105][3],ans;inline int read(){ int x=0,w=0; char ch=0; while (!isdigit(ch)) w|=ch=='-',ch=getchar(); while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return w?-x:x;}inline int max(int a,int b) {return a>b?a:b;}int main(int argc, char const *argv[]){ N=read(); M=read(); for (Re i=1; i<=N; ++i) d[i][0]=read(),d[i][1]=read(),d[i][2]=read(); memset(f,0x80,sizeof(f)); f[0][0][0]=f[0][0][1]=f[0][0][2]=0; for (Re i=1; i<=M; ++i) for (Re j=1; j<=N; ++j) //枚举要做决策的积木 for (Re b=0; b
y1) swap(x1,y1); if (x2>y2) swap(x2,y2); if (x1>=x2&&y1>=y2) f[i][j][ns]=max(f[i][j][ns],f[i][b][bs]+d[j][(ns+2)%3]); f[i][j][ns]=max(f[i][j][ns],f[i-1][b][bs]+d[j][(ns+2)%3]); } for (Re i=1; i<=N; ++i) ans=max(ans,max(f[M][i][0],max(f[M][i][1],f[M][i][2]))); printf("%d\n",ans); return 0;}

转载于:https://www.cnblogs.com/Alkri/p/9533149.html

你可能感兴趣的文章
排序算法(转)
查看>>
windows自带的可生成各种数据库连接字符串工具打开方法
查看>>
Linux查看系统开机时间(转)
查看>>
form表单中method的get和post区别
查看>>
【做题】arc068_f-Solitaire——糊结论
查看>>
Poj 1094 拓扑排序 水题
查看>>
Oracle SQL查询,日期过滤条件要注意的一点
查看>>
链表快排
查看>>
链表操作合集
查看>>
leetcode852 C++ 20ms 找最高峰 序列先增后减
查看>>
JavaScript深入系列(一)--原型和原型链详解
查看>>
一点感想
查看>>
产生随机数
查看>>
vm center(VC)5.1登陆密码忘记了怎么办?
查看>>
TFS 2015 敏捷开发实践 – 看板的使用
查看>>
UINavigationController的简单使用
查看>>
Python命名规范
查看>>
50款漂亮的国外婚礼邀请函设计(上篇)
查看>>
MD5加密简单算法
查看>>
安装Qcreator2.5 + Qt4.8.2 + MinGW_gcc_4.4 (win7环境)
查看>>