Stacking Plates UVA - 1289 dp 加离散化

博客讲述了如何解决UVA 1289题目,该题目涉及将盘子通过split和join操作叠成一堆,目标是最小化操作次数。博主发现答案与最终状态的相邻异色对数量相关,并将问题转化为求最小异色对数。通过定义动态规划状态dp[i][j]表示处理完半径小于等于i的圆盘且最下面为第j种颜色,但由于数据规模可能引起超时,于是采取离散化的方法优化。博主在实现过程中因状态转移错误导致WA,提醒读者注意细节。
摘要由CSDN通过智能技术生成

题意:有n(1<=n<=50) 堆盘子,第i堆盘子有hi个盘子(1 <= hi <= 50),从上到下直径不减.所有盘子的直径均不超过10000。有如下两种操作.
split : 把一堆盘子从某个位置处分成上下两堆。
join:把一堆盘子a放到另一堆盘子b的顶端,要求是a底部的盘子的直径不超过b顶端盘子的直径.
你的任务是用最少的操作把所有盘子叠成一堆.

其实应该很容易想到,如果我们把不同的堆刷成不同的颜色。那么操作数就与最终状态的相邻异色对的数量ans有关 写几组数据后可以发现最终答案为2*ans-n+1。
那么 我们就可以把问题转化成为求最小异色对数。
如果定义dp[i][j] 为处理完半径小于等于i的圆盘 放在最下面的圆盘为第j种颜色。 这样定义的正确性和转移方程都很容易写。
但是因为i=10000 所以单次询问复杂度为O(10000*(n^2)) 再加上多组输入 数据变态一点(其实好像数据很弱,官方下载的数据全都是单组输入)很有可能超时。
然后因为最多只有2500个盘子 我们其实可以离散化一下。
然后就很(超)好(麻)写(烦)了。
WA了不知道多少发了 结果发现状态转移时没取最小值 ORZ。
代码写得很乱 没有可参考性

# include<iostream>
# include<cstdio>
# include<cstring>
# include<algorithm>
#include<vector>
#define mem(a,b) memset(a,b,sizeof a)
using namespace std;
int dp[2505][50];// dp[i][j]表示前i种直径的圆盘处理完后 第i种圆盘以第j堆结尾时的最小异色对数
class node
{
public:
    int r,sum,id;
    bool  operator <  (const node 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值