问题听起来像这样:
凯文有N个朋友和一栋楼。他想组织一个 在那栋楼里聚会,他邀请了1个朋友/天。凯文 不幸的是,有脾气暴躁的邻居,他们对 凯文的派对做的噪音。为此,凯文希望尽量减少 他的派对的噪音水平。(噪音水平等于 大楼里的朋友)为了做到这一点,有一天他可以 通过要求他的朋友离开来清理建筑物(他可以这样做K次,K不同的日子)。(例如:他清除了 在第 2 天之后建造,所以在第 3 天,当他邀请另一个朋友时,对于 第 3 天噪音水平将为 1,因为过去一天他清除了 建筑;如果他没有在第2天清理建筑物,噪音水平 第 3 天将是 3(第 2 天为 1,第 1 天和新邀请的朋友为 1),第 1、2 和 3 天的总噪音水平为 1+2+3=6)。
为了更好地理解任务:
输入:
5 2 (N, K)
输出:
7
解释:
在输入示例中,将按以下顺序邀请 N 个朋友参加聚会:
1 (day 1) 1 (day 1)
1 (day 2) so in the building for each day will be present 2 (day 2)
1 (day 3) -------------------------------------------------> 3 (day 3)
1 (day 4) (without clearing the building) 4 (day 4)
1 (day 5) 5 (day 5)
-----(+)
15
因此,清除建筑物 0 次 (K=0),噪音水平将为 15。
清除建筑物 1 次 (K=1),总和为:
(0 times)
1 1
__ 2 __ clearing the building after day 2 2
3 -----------------------------------> 1
4 2
5 3
----(+)
9
在这种情况下(K = 1),另一种解决方案可能是在第3天之后清除相同的总和。
清除 2 次 (K=2):
(0 times)
1 1
__ 2 __ clearing the building after day 2 & 3 2
__ 3 __ --------------------------------------> 1
4 1
5 2
----(+)
7
我有解决方案,但我不明白!
我试过了,拿了一些其他案例,但仍然一无所获,也许你们可以解释为什么解决方案是这样的。
总和 (N, K) 的计算方式如下:
sum(N, K) = 清除建筑物 K 次的最小噪音水平 (K>=0)
C++代码:
int sum(int n)
{
return n * (n + 1) / 2;
}
int solve(int n, int k)
{
int p = k + 1;
int mp = n/p;
int bp = (n+p-1)/p;
int nmaj = n%p;
int nmic = p-nmaj;
return nmic * sum(mp) + nmaj*sum(bp);
}
每个变量的用途是什么?
nmic * sum(mp)
和nmaj*sum(bp)
计算什么?
!!!
对于上面的例子(在开头 - N=5,K=2),我调试了代码并编写了N=5, K=0..2
每个变量的值,希望得到这个想法,但没有成功。我将为您发布它们,也许您会明白这个想法,然后向我解释(我是算法问题的新手)。
是这样的:
每种情况的变量值
我再说一遍,我试图理解几个小时,但没有成功。这不是家庭作业。谢谢!
代码是这样的:
int p = k+1;
p
是划分天数的"部分"数(例如:
int mp = n/p;
mp
是次要部件的天数,在示例中为 1 (Day5)。它计算为天数与零件数的下限。
int bp = (n+p-1)/p;
bp
是较大部分的天数,示例中为 2(第 1 天 + 第 2 天或第 3 天 + 第 4 天)。我真的没有得到确切的数学原理,但这就是它的计算结果
int nmaj = n%p;
int nmic = p-nmaj;
nmaj
是主要部件的数量,在示例中为 2(第 1 天 + 第2 天和第 3 天 + 第 4 天),nmic
是次要部件的数量(第 5 天为 1)。
nmic * sum(mp) + nmaj*sum(bp);
这只返回次要零件的数量 * 次要零件的累计值 + 主要零件的数量 * 主要零件的累积值
sum
函数只是初始元素 = 1 的特殊情况下的算术级数(或算术级数之和)的公式