Uva-1289 Stacking Plates
动态规划的一道题目,看了别人的代码之和自己实现的。首先是读入数据,统计每一堆中不同大小盘子的个数以及所有的盘子中大小不同的个数。然后统计对于每一类的盘子存在于哪些堆中以及每一堆中存在着哪些种类的盘子。紧接着,开始动态规划的过程,利用dp[i][j]表示将第1~i类的盘子全部堆好,并且最终这些盘子是放置于第j堆中,那么在堆积第i类的盘子之前肯定需要把第i-1类的盘子堆积好,所以当我们选取的第i类盘子最终的落脚点和第i-1类的盘子的最终的落脚点不同的时候,那么肯定是选取dp[i-1][k]+int(G[i].size())-exist[k][i]?1:0的最小值,当选取的第i类盘子和第i-1类盘子最终的落脚点相同的时候就选取 dp[i-1][k],并且比较得出最小值。注意上面的这种情况是当G[i]的大小为1的时候。当G[i]大小不为1的时候,出于避免重复的考虑(个人理解,如果有其他的理解欢迎在评论区交流),就直接舍弃这种情况,具体实现见如下代码:
#include<iostream>
#include<vector>
#include<string>
#include<set>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<deque>
using namespace std;set<int> G[2510];//第i类盘子所存在的堆的编号
int exist[55][2510];//第i堆中是否存在第j类的盘子
int dp[2510][55];class Solve{public:int n;int plate[55][55];int total[2510];int ind,amount;int Inf = 1047483647;void Init(){ind = 0;memset(exist,0,sizeof(exist));for (int i = 0; i < 2510; i++) G[i].clear();for (int i = 1; i <= n; i++){cin >> plate[i][0];for (int j = 1; j <= plate[i][0]; j++){cin >> plate[i][j];total[++ind] = plate[i][j];}plate[i][0] = unique(plate[i] + 1, plate[i] + 1 + plate[i][0]) - (plate[i]+1);}sort(total+1,total+ind+1);amount = unique(total+1, total + ind+1) - (total+1);for (int i = 1; i <= n; i++){for (int j = 1; j <= plate[i][0]; j++){plate[i][j] = lower_bound(total+1, total +1 + amount, plate[i][j]) - total;G[plate[i][j]].insert(i);exist[i][plate[i][j]] = 1;}}}void Deal(){Init();memset(dp,0x3f,sizeof(dp));for (int i : G[1]) dp[1][i] = G[1].size() - 1;for (int i = 2; i <= amount; i++){for (int j : G[i]){for (int k : G[i - 1]){if (j != k){dp[i][j] = min(dp[i][j], dp[i - 1][k] + int(G[i].size()) - (exist[k][i] ? 1 : 0));}else{//j==kdp[i][j] = min(dp[i][j], (G[i].size() == 1 )? dp[i - 1][j] : Inf);}}}}int ans = Inf;for (int j = 1; j <= n; j++) ans = min(ans, dp[amount][j]);cout << ans*2-(n-1) << endl;}
};int main(){Solve a;int Case = 1;while (cin >> a.n){cout << "Case " << Case++ << ": ";a.Deal();}return 0;
}
Uva-1289 Stacking Plates相关推荐
- 【Uva 1289】Stacking Plates
[Link]: [Description] 有n(1≤n≤50)堆盘子,第i堆盘子有hi个盘子(1≤hi≤50),从上到下直径不减.所有盘 子的直径均不超过10000.有如下两种操作. split:把 ...
- UVa 103 - Stacking Boxes(dp求解)
题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...
- UVA 103 Stacking Boxes 套箱子 DAG最长路 dp记忆化搜索
题意:给出几个多维的箱子,如果箱子的每一边都小于另一个箱子的对应边,那就称这个箱子小于另一个箱子,然后要求能够套出的最多的箱子. 要注意的是关系图的构建,对箱子的边排序,如果分别都小于另一个箱子就说明 ...
- UVA 103 Stacking Boxes
终于完成了啊,这可是我自己独立做的第一道DP题!激动ing--这题在白书里是DAG上的DP,可是我看不懂,比如怎么建图我就不会,所以代码都是自己想的.图我不会建,只好动下脑子,刚开始是想用二维数组保存 ...
- 【DP】UVA 103 Stacking Boxes 输出路径
类似于叠箱子 对于箱子a : (a1,a2,a3),b : (b1,b2,b3) 存在一个顺序ai<bj,ak<bi,aj<bk 就表示a可以到b #include <stdi ...
- UVa 103 - Stacking Boxes
题目大意:矩阵嵌套,不过维数是多维的.有两个个k维的盒子A(a1, a1...ak), B(b1, b2...bk),若能找到(a1...ak)的一个排列使得ai < bi,则盒子A可嵌套在盒子 ...
- BZOJ 3982 Stacking Plates 解题报告
我们首先可以得到:如果有一堆盘子里有一些相邻的盘子的直径相等,那么自然这些盘子可以统一处理,就可以缩成一个了. 然后我们接着考虑给每一堆盘子都染上一种颜色,那么操作的次数 step = diff * ...
- 紫书《算法竞赛入门经典》
紫书<算法竞赛入门经典>题目一览 第3章 数组和字符串(例题) UVA 272 TEX Quotes UVA 10082 WERTYU UVA 401 Palindromes UVA 34 ...
- 个人DP训练(基础版)
题目链接 hdu 2955 Robberies 01背包,转化为求被抓的概率. 题目链接 hdu 1864 最大报销额 01背包,每张发票的总额为容量和价值,注意预处理数据,对 ...
最新文章
- Arm architecture 第一章
- 使用 SSH 免密码登录连接远程服务器
- Spring定时任务注解@Scheduled+@EnableAsync用法详解(简单说明+应用场景+demo源代码+执行过程分析)
- OAuth2(一)——核心概念
- netsh interface portproxy 转发不生效_SecureCRT远程端口转发不生效的解决方法
- VHDL移位寄存器的设计与实现
- Python下使用optparse模块实现对多个文件进行统计【二】
- Springboot+Mysql物流快递在线寄查快递系统
- 诗歌rails之获取本地ip地址
- 软件工程师如何应对面试的可怕“反乌托邦世界”?
- vue-router 设置路由在新窗口打开页面
- dpi数据接入shell脚本
- SQL Server2005 表分区三步曲(zz)
- 一场分销裂变活动,不止是发发朋友圈这么简单
- 【多元统计分析】09.独立性检验与正态性检验
- 岭南东方品牌连签两店,持续发力旅游目的地
- 全球营商环境报告及数据(2004-2020年)
- h.265/HEVC解码器verilog实现
- The Last Samurai 最后的武士**
- Ratatype - 在线打字教程,提高打字速度