Algorithm 算法-您必须进行多少更改才能获得;“令人印象深刻”;数字集 问题

Algorithm 算法-您必须进行多少更改才能获得;“令人印象深刻”;数字集 问题,algorithm,dynamic-programming,Algorithm,Dynamic Programming,一组令人印象深刻的数字是一组,其中包含k个数量的k个数字,每个数字都包含k个数量 例如(5,5,5,5,5),(2,2,3,3,3,1)和(2,2,1)都是令人印象深刻的集合 (3,3,2)不是一个令人印象深刻的集合,因为有两个3s(应该是三个)和一个2(应该是两个) 有一个n整数ai列表,因此(1≤ N≤ 2000, 1 ≤ 人工智能≤ 2000年) 找出最小的变化量,以获得令人印象深刻的一组。你可以一次换一个号码。顺序不重要。最后一盘是什么并不重要 例子 输入:(3,4,3,2,1)->(

一组令人印象深刻的数字是一组,其中包含k个数量的k个数字,每个数字都包含k个数量

例如
(5,5,5,5,5)
(2,2,3,3,3,1)
(2,2,1)
都是令人印象深刻的集合

(3,3,2)
不是一个令人印象深刻的集合,因为有两个
3
s(应该是三个)和一个
2
(应该是两个)

有一个
n
整数ai列表,因此(1≤ N≤ 2000, 1 ≤ 人工智能≤ 2000年)

找出最小的变化量,以获得令人印象深刻的一组。你可以一次换一个号码。顺序不重要。最后一盘是什么并不重要

例子
  • 输入:(3,4,3,2,1)->(3,3,3,2,1)->(3,3,3,2,2)=>输出:2
  • 输入:(5,5,5,5,5,5,5,5)输出:2
  • 输入:(2,2,3,3)->(2,3,3)->(1,3,3)=>输出:2
输入/输出 函数的输入是一个列表。输出为
int
,表示最小更改量

旁注

程序应该用C++编写,内存容量为64 MB。当然,我不是在寻求解决方案,而是想得到一个关于如何在算法方面做的提示。

试着回答这个问题:“对于任何
0
您需要确定的第一件事是分区方面:哪些唯一整数集将与输入集的大小相加?对于每个这样的组合,找到最小的更改距离很简单

对于上述给定情况,您有以下可能性:

  • 4:{4},{1,3}
  • 5:{5},{1,4},{2,3}
  • 7:{7},{1,6},{2,5},{3,4},{1,2,4}
分区问题在很多地方都有很好的介绍;我将把这项研究留给您。请注意,“三角形”数(整数的和1-n)很有用,因为它们描述了限制分区。例如,
T(3)基本上,它等于。首先构建表,然后提取成本最低的子集和的一个解

例如,对于
1,2,3,4,5,5
,我们在数组中有
6
个位置和五个数字
1,2,3,4,5
。从这些数字中,我们需要找到总计为
6
的子集。然后选择一个变化次数最少的子集来构建一个令人印象深刻的集合

算法的复杂度是
O(n^2)

#包括
#包括
#包括
#包括
#包括
#包括
常数短N=2000;
短dp[N+1][N];
const short NO=std::numeric_limits::max();
课堂印象深刻{
短款;
std::数组计数={0};
const std::向量和输入;
无效子项MDP()
{
用于(短i=1;短i=0){
如果(dp[i-1][j-i]!=否)
dp[i][j]=std::min(dp[i][j],(短)(dp[i-1][j-i]+to_-replace));
}
}
}
}
}
公众:
令人印象深刻(const std::vector&v):输入(v)
{

对于(int i=0;i这里有一个递归公式,其中
g(i,j)
表示实现基数
i
集所需的最小更改,考虑到小于
j
O(n*n)
搜索空间:

函数f(A){
常数n=A.长度;
常量计数=新数组(n+1)。填充(0);
为了(让我举个例子)

如果(我这个练习的重点是算法。任何提示都是解决方案。这个解决方案的算法复杂性是什么?我用这个解决方案编写了一个Python脚本。这是一个正确的方法,给出了正确的答案,但是生成一组加起来等于2000的唯一整数非常慢,会产生很多不同的答案。为什么5 imp我们不能把它变成1个一个移动吗?“我想我们应该只使用提供的数字,但是你是对的。也许我需要重新考虑整个算法。”现在,我把1到2000的所有数字都考虑在内。谢谢指点。不过,我不确定是不是被问到了。uild令人印象深刻的集合,而不是数字,因此
32332
计数。我已经在Linux上编译了代码,除了它编译的两个缺少的头。分段错误仍然存在。似乎构造函数中有一个bug。它应该更小,而不是更小或相等,因为您正在以0开始迭代。更改后,它工作得非常好。我将验证fy,如果它能与更大的数组一起工作。你太棒了!谢谢你嘿,这看起来像是@Yola提出的一个很好的替代方案。但是它和他的算法有着同样的问题:它不能扩展到2000个数字。我已经运行了10分钟,运行了2000个随机整数,它只是不想结束。我认为复杂性太高,但我也不想不要认为用O(nlogn)或更好的方法来实现这一点是可能的。你的算法的复杂度超过O(n^2),我认为这不是一个可行的选择。尽管如此,付出了巨大的努力。我非常感谢@DCzajkowski感谢你的阅读。我的算法的复杂度是O(n^2)-只有n*n相关(I,j)组合。代码只是一个大纲,没有。一个表格版本可能也会减少对负i的调用。我很惊讶你说Yola的代码没有扩展到2000。它不是O(n^2)吗?不是。dp部分是O(n^2),但回溯部分显然不是。@DCzajkowski我添加了备忘录和一个包含2000个随机整数的示例。代码段中的例程在我的浏览器中需要3~5秒才能完成2000个数字。我认为是较低级别的表格版本