给定天数的最佳读取列表

一个人下定决心要在“k”天内完成这本书,但他从来不想在这两天之间停下一章。找到最佳的章节分配,这样这个人就不会阅读太多额外/更少的页面。

null

例子:

Input:  Number of Days to Finish book = 2
        Number of pages in chapters = {10, 5, 5}
Output: Day 1:  Chapter 1
        Day 2:  Chapters 2 and 3

Input:  Number of Days to Finish book = 3
        Number of pages in chapters = {8, 5, 6, 12}
Output: Day 1:  Chapter 1
        Day 2:  Chapters 2 and 3 
        Day 2:  Chapter 4

目标是将每天阅读的页面与平均页数之间的差异之和降至最低。如果平均页数为非整数,则应将其四舍五入为最接近的整数。

在上面的示例2中,平均页数为(8+5+6+12)/3=31/3,四舍五入为10。因此,对于上面显示的输出,每天的平均页数和页数之间的差异是“abs(8-10)+abs(5+6-10)+abs(12-10)”,即5。值5是差和的最佳值。

考虑上面的例子2,其中一本书有4章,第8, 5, 6页和第12页。用户希望在3天内完成。上述场景的图形表示为:,

BookChapter1

在上图中,顶点代表章节,边e(u,v)代表从“u”读到“v”的页数。增加了Sink节点,表示书的结尾。

首先,计算一天平均要阅读的页数(这里是31/3,大约10页)。新的边权重e’(u,v)将是平均差| avg–e(u,v)|。上述问题的修正图是,

BookChapter2

幸亏 犰狳 感谢你在评论中提出这个想法。

我们的想法是从第1章开始,做一个DFS来查找边数为“k”的水槽。继续将访问的顶点存储在一个数组中,比如“路径[]”。如果我们到达目标顶点,且路径和小于最优路径,则更新最优分配最优_路径[]。请注意,图表是DAG,因此在DFS期间不需要考虑周期。 下面是C++实现的相同,邻接矩阵是用来表示图的。以下项目主要分为4个阶段。 1) 构造一个有向无环图。 2) 使用DFS找到最佳路径。 3) 打印找到的最佳路径。

C++

// C++ DFS solution to schedule chapters for reading in
// given days
# include <iostream>
# include <cstdlib>
# include <climits>
# include <cmath>
using namespace std;
// Define total chapters in the book
// Number of days user can spend on reading
# define CHAPTERS 4
# define DAYS 3
# define NOLINK -1
// Array to store the final balanced schedule
int optimal_path[DAYS+1];
// Graph - Node chapter+1 is the sink described in the
//         above graph
int DAG[CHAPTERS+1][CHAPTERS+1];
// Updates the optimal assignment with current assignment
void updateAssignment( int * path, int path_len);
// A DFS based recursive function to store the optimal path
// in path[] of size path_len.  The variable sum stores sum of
// of all edges on current path.  k is number of days spent so
// far.
void assignChapters( int u, int * path, int path_len, int sum, int k)
{
static int min = INT_MAX;
// Ignore the assignment which requires more than required days
if (k < 0)
return ;
// Current assignment of chapters to days
path[path_len] = u;
path_len++;
// Update the optimal assignment if necessary
if (k == 0 && u == CHAPTERS)
{
if (sum < min)
{
updateAssignment(path, path_len);
min = sum;
}
}
// DFS - Depth First Search for sink
for ( int v = u+1; v <= CHAPTERS; v++)
{
sum += DAG[u][v];
assignChapters(v, path, path_len, sum, k-1);
sum -= DAG[u][v];
}
}
// This function finds and prints optimal read list.  It first creates a
// graph, then calls assignChapters().
void minAssignment( int pages[])
{
// 1) ............CONSTRUCT GRAPH.................
// Partial sum array construction S[i] = total pages
// till ith chapter
int avg_pages = 0, sum = 0, S[CHAPTERS+1], path[DAYS+1];
S[0] = 0;
for ( int i = 0; i < CHAPTERS; i++)
{
sum += pages[i];
S[i+1] = sum;
}
// Average pages to be read in a day
avg_pages = round(sum/DAYS);
/* DAG construction vertices being chapter name &
* Edge weight being |avg_pages - pages in a chapter|
* Adjacency matrix representation  */
for ( int i = 0; i <= CHAPTERS; i++)
{
for ( int j = 0; j <= CHAPTERS; j++)
{
if (j <= i)
DAG[i][j] = NOLINK;
else
{
sum = abs (avg_pages - (S[j] - S[i]));
DAG[i][j] = sum;
}
}
}
// 2) ............FIND OPTIMAL PATH................
assignChapters(0, path, 0, 0, DAYS);
// 3) ..PRINT OPTIMAL READ LIST USING OPTIMAL PATH....
cout << "Optimal Chapter Assignment :" << endl;
int ch;
for ( int i = 0; i < DAYS; i++)
{
ch = optimal_path[i];
cout << "Day" << i+1 << ": " << ch << " " ;
ch++;
while ( (i < DAYS-1 && ch < optimal_path[i+1]) ||
(i == DAYS-1 && ch <= CHAPTERS))
{
cout <<  ch << " " ;
ch++;
}
cout << endl;
}
}
// This function updates optimal_path[]
void updateAssignment( int * path, int path_len)
{
for ( int i = 0; i < path_len; i++)
optimal_path[i] = path[i] + 1;
}
// Driver program to test the schedule
int main( void )
{
int pages[CHAPTERS] = {7, 5, 6, 12};
// Get read list for given days
minAssignment(pages);
return 0;
}


Python3

# Python3 DFS solution to schedule chapters
# for reading in given days
# A DFS based recursive function to store
# the optimal path in path[] of size path_len.
# The variable Sum stores Sum of all edges on
# current path. k is number of days spent so far.
def assignChapters(u, path, path_len, Sum , k):
global CHAPTERS, DAYS, NOLINK, optical_path, DAG, Min
# Ignore the assignment which requires
# more than required days
if (k < 0 ):
return
# Current assignment of chapters to days
path[path_len] = u
path_len + = 1
# Update the optimal assignment if necessary
if (k = = 0 and u = = CHAPTERS):
if ( Sum < Min ):
updateAssignment(path, path_len)
Min = Sum
# DFS - Depth First Search for sink
for v in range (u + 1 , CHAPTERS + 1 ):
Sum + = DAG[u][v]
assignChapters(v, path, path_len, Sum , k - 1 )
Sum - = DAG[u][v]
# This function finds and prints
# optimal read list. It first creates a
# graph, then calls assignChapters().
def MinAssignment(pages):
global CHAPTERS, DAYS, NOLINK, optical_path, DAG, MIN
# 1) ............CONSTRUCT GRAPH.................
# Partial Sum array construction S[i] = total pages
# till ith chapter
avg_pages = 0
Sum = 0
S = [ None ] * (CHAPTERS + 1 )
path = [ None ] * (DAYS + 1 )
S[ 0 ] = 0
for i in range (CHAPTERS):
Sum + = pages[i]
S[i + 1 ] = Sum
# Average pages to be read in a day
avg_pages = round ( Sum / DAYS)
# DAG construction vertices being chapter name &
# Edge weight being |avg_pages - pages in a chapter|
# Adjacency matrix representation
for i in range (CHAPTERS + 1 ):
for j in range (CHAPTERS + 1 ):
if (j < = i):
DAG[i][j] = NOLINK
else :
Sum = abs (avg_pages - (S[j] - S[i]))
DAG[i][j] = Sum
# 2) ............FIND OPTIMAL PATH................
assignChapters( 0 , path, 0 , 0 , DAYS)
# 3) ..PROPTIMAL READ LIST USING OPTIMAL PATH....
print ( "Optimal Chapter Assignment :" )
ch = None
for i in range (DAYS):
ch = optimal_path[i]
print ( "Day" , i + 1 , ": " , ch, end = " " )
ch + = 1
while ((i < DAYS - 1 and ch < optimal_path[i + 1 ]) or
(i = = DAYS - 1 and ch < = CHAPTERS)):
print (ch, end = " " )
ch + = 1
print ()
# This function updates optimal_path[]
def updateAssignment(path, path_len):
for i in range (path_len):
optimal_path[i] = path[i] + 1
# Driver Code
# Define total chapters in the book
# Number of days user can spend on reading
CHAPTERS = 4
DAYS = 3
NOLINK = - 1
# Array to store the final balanced schedule
optimal_path = [ None ] * (DAYS + 1 )
# Graph - Node chapter+1 is the sink
#          described in the above graph
DAG = [[ None ] * (CHAPTERS + 1 )
for i in range (CHAPTERS + 1 )]
Min = 999999999999
pages = [ 7 , 5 , 6 , 12 ]
# Get read list for given days
MinAssignment(pages)
# This code is contributed by PranchalK


输出:

 
Optimal Chapter Assignment :
Day1: 1
Day2: 2 3
Day3: 4

本文由 巴拉吉S 。如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请发表评论。

© 版权声明
THE END
喜欢就支持一下吧
点赞12 分享