博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDOJ 1050 贪心? 好题
阅读量:6909 次
发布时间:2019-06-27

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

题目链接:

首先要注意,对门的两个房间不能同时移桌子。我们读入房间号时,要对房间号做处理(比如令房间号=(房间号-1)/2),使得对门的两个房间的编号相同,方便处理。

其次,本题我给出两种解法。

解法一的思想是,将一次从from->to的移动看成一个线段,n次移动可以看成n条线段。将这n条线段画在数轴上,则最少需要移动的次数,等于线段重叠(两条线段至少包含相同的一点算作重合)的最大层数。这种解法似乎没有包含典型的贪心思想,至少我的愚见是这样。这种解法可以用数学归纳法证明。

解法二的思想是,先对所有移动(from->to)按from由小到大的顺序排序,然后每次按from从前往后取移动(这里的移动是指移动一张桌子),直到取不出来,算一次移动(这里的移动指移动若干张桌子)。这种解法更像贪心,但是我无法证明这种解法的正确性。如果哪位知道如何证明,请赐教。

 


解法一。

#include 
#include
using namespace std;const int LEN = 200;int overlapCount[LEN];int main (){ int caseNum; scanf("%d",&caseNum); for (int i = 1;i <= caseNum;i ++) { int moveNum; scanf("%d",&moveNum); memset(overlapCount, 0, sizeof(overlapCount)); for (int j = 1;j <= moveNum;j ++) { int from, to; scanf("%d%d",&from,&to); from = (from - 1) / 2; to = (to - 1) / 2; if (from > to) swap(from, to); for (int k = from;k <= to;k ++) overlapCount[k] ++; } int max = 0; for (int j = 0;j < LEN;j ++) max = max > overlapCount[j] ? max : overlapCount[j]; printf("%d\n", max * 10); } return 0;}

 

解法二。

#include 
#include
#include
using namespace std;class Move{public: int from, to; int isMoved;};vector
moves,onceMoveRec;//onceMoveRec记录一次移动中的所有移动计划int judgeAllMoved(int moveNum){ for (int i = 0;i < moveNum;i ++) if (moves[i].isMoved == 0) return 0; return 1;}int judgeCanMove(Move aMove){ //front是from小的move Move front,back; for (int i = 0;i < onceMoveRec.size();i ++) { if (onceMoveRec[i].from <= aMove.from) { front = onceMoveRec[i]; back = aMove; } else { back = onceMoveRec[i]; front = aMove; } if (back.from <= front.to) return 0; } return 1;}int cmp(const Move &m1, const Move &m2){ return m1.from < m2.from;}int main (){ int caseNum; scanf("%d",&caseNum); for (int i = 1;i <= caseNum;i ++) { moves.clear(); int moveNum; scanf("%d",&moveNum); Move aMove; //读入所有桌子的移动计划 for (int j = 1;j <= moveNum;j ++) { scanf("%d%d",&aMove.from,&aMove.to); aMove.from = (aMove.from - 1) / 2; aMove.to = (aMove.to - 1) / 2; if (aMove.from > aMove.to) swap(aMove.from,aMove.to); aMove.isMoved = 0; moves.push_back(aMove); } //按to从前往后排序。不排序是错的,我也不知道为什么 sort(moves.begin(),moves.end(),cmp); int moveCount = 0; int isAllMoved = 1; //如果没有移完 while ( ! judgeAllMoved(moveNum)) { onceMoveRec.clear(); for (int i = 0;i < moveNum;i ++) { if (moves[i].isMoved == 1) continue; if (judgeCanMove(moves[i])) { onceMoveRec.push_back(moves[i]); moves[i].isMoved = 1; } } moveCount ++; } printf("%d\n",moveCount * 10); } return 0;}

转载于:https://www.cnblogs.com/peaceful-andy/archive/2012/08/22/2651629.html

你可能感兴趣的文章
SQL Server 大数据搬迁之文件组备份还原实战
查看>>
区块链核心技术:拜占庭共识算法之PBFT
查看>>
数据挖掘中的 10 大算法
查看>>
iOS开发系列- 视频MPMoviePlayerController
查看>>
iOS -- 拨打电话
查看>>
模仿CyclicBarrier,自定义自己屏障类
查看>>
Vue+Vue-router微信分享功能
查看>>
1.数码相框-相框框架分析(1)
查看>>
Javascript中的原型继承具体解释
查看>>
Python基础之(三)----PyGame安装步骤
查看>>
MYSQL SHOW VARIABLES简介
查看>>
Win8Metro(C#)数字图像处理--2.8图像线性变换
查看>>
解决eclipse不识别Android手机的问题
查看>>
axel命令 文件下载
查看>>
python基础训练题1-列表操作
查看>>
编程学习资源
查看>>
selenium+python自动化95-弹出框死活定位不到
查看>>
[Asp.net core]使用Polly网络请求异常重试
查看>>
Java探针-Java Agent技术-阿里面试题
查看>>
densenet
查看>>