问题描述:
临近期末,让小东头疼的考试又即将到来了,而且是小东最不喜欢的科目,遗憾的事,
小东得知d天后他必须参加此次考试,小东的父亲对他非常严格,要求他立即开始复习
功课。为照顾她的情绪,父亲要求她每天该科目的学习时间在iminTime到imaxTime之间
,并计划在考试前检查小东是否按要求做了。若未能完成,小东将会受到惩罚。
现在小东的父亲要求检查小东的备考情况。遗憾的事,由于专注于备考,小东只是记录
了自己备考的总时间sumTime,并没有记录每天复习所用的时间,也不知道准备情况是否
符合父亲的要求。他想知道是否能够制作一个满足需求的时间表以应付父亲的检查
输入:
输入中有多组测试数据。每组测试数据的第一行包含两个整数d和sumTime,1<=d<=30,
0<=sumTime<=240,分别表示小东复习的天数及每天用于复习的时间之和。紧随其后的d行
中,每行包括两个空格分隔的整数,为小东父亲要求小东在这一天用于复习时间的范围
iminTime和imaxTime
0<=iminTime<=imaxTime<=8.
输出:
对每组测试数据,若能够做出一个满足小东父亲要求的时间表,则在单独的一行中输出Yes
,并在随后的一行中给出每天复习花费的时间。否则输出No。若满足要求的时间表不唯一,
小东希望给父亲留下比较用功的映像,开始时每天复习的时间比较长
样例输入:
1 48
5 7
2 5
0 1
3 5
样例输出:
No
Yes
1 4
问题分析:
利用贪心实现,告知了开始复习的时间比较长,设总共有d天,对于第i天,
则选择满足条件的最大值,也即满足后面d-i天的需要,剩余时间必须在后面d-i天的最小值
与最大值之间,
#include <iostream>
using namespace std;
int main()
{
int Day;
int SumTime;
while(cin>>Day>>SumTime)
{
int *minTime = new int[Day];
int *maxTime = new int[Day];
int *dayTime = new int[Day]; //每天复习时间
for (int i = 0; i < Day; i++)
{
cin>>minTime[i]>>maxTime[i];
}
int tmpMin = 0;
int tmpMax = 0;
for (int i = 0; i < Day; i++)
{
tmpMin += minTime[i];
tmpMax += maxTime[i];
}
bool flag = true;
for (int i = 0; i < Day; i++)
{
if (SumTime < tmpMin || SumTime > tmpMax)
{
flag = false;
break;
}
//求得第i天后面所需总时间范围
tmpMin -= minTime[i];
tmpMax -= maxTime[i];
//求得第i天满足条件的时间范围
int tmin = SumTime - tmpMax;
int tmax = SumTime - tmpMin;
int k;
for (k = tmax; k >= tmin; k--)
{
//得到满足条件的最大时间
if (k >= minTime[i] && k <= maxTime[i])
{
dayTime[i] = k;
break;
}
}
if (k < tmin)
{
flag = false;
break;
}
else{
SumTime -= k;
}
}
if (flag)
{
cout << "Yes" << endl;
for (int i = 0; i < Day; i++)
{
cout << dayTime[i] << " " << endl;
}
}
else{
cout << "No" << endl;
}
}
return 0;
}