如何解决我需要一些关于动态规划的建议
问题来了: 哈娜是一个数学创造者。最初,他有一个数字 n。每次他执行一个动作时,他都会移除任何元素x,使得x>1,然后在相同的位置插入3个数字,顺序为:floor(x/2),x mod 2,floor(x/2)。他必须继续这个操作,直到他收到满是 0 和 1 的列表。
鉴于此,该列表是 1 索引的(列表的第一个索引为 1)。实现一个函数 sumOfOnes 来计算列表中 l 到 r 范围内的数字 1 的个数之和。
注意:
-
时间限制为 2 秒
0
0
-
r >= l
-
l >= 1
我使用bottom_up方法(动态规划)来解决这个问题int limit time。这是我的代码:
string hana(long long int n)
{
string* memoize = new string[n+1];
memoize[0] = "0";
memoize[1] = "1";
for(long long int i = 2; i <= n; ++i)
{
if(i%2 == 0) memoize[i] = memoize[i/2] + "0" + memoize[i/2];
else memoize[i] = memoize[i/2] + "1" + memoize[i/2];
}
return memoize[n];
}
//
long long int sumOfOnes (long long int n,long long int l,long long int r){
string result = hana(n);
long long int ans = 0;
for(long long int i = l - 1; i <= r - 1; ++i)
{
if(result[i] == '1') ++ans;
}
return ans;
}
它适用于小输入,但由于内存不足,它不适用于大输入! 我真的需要一些关于如何处理大量输入的建议。 非常感谢!!!
解决方法
首先,除了几个设计缺陷之外,你还有一个严重的内存泄漏问题,因为你在没有适当删除的情况下堆分配了一个本地数组。
string* memoize = new string[n+1];
不要在本地这样做,为此使用 std::vector :
auto memoize = std::vector<std::string>(n + 1);
进一步,您要为每个实际值请求一次又一次地重新创建数组。至少对于您当前使用完全初始化数组的求解方案,应该避免这种情况,使用 hana 数组的更“全局”存储位置(预先分配最大可能的 N)!
对于您的实际算法问题,这里没有更深入的数学洞察力,并且感觉原始问题是用更多细节/精确度陈述的...:
您将永远无法以可接受的方式使用当前的 n 大约 50 的方法解决此问题。
关键是:这是一个常见的对数问题类,例如见二分查找。您应该尝试重新设计对递归函数调用访问的数组访问,因此对第 n 个元素的访问始终通过函数调用完成,并且只有前两个元素实际上是“具体的”。如果首先不进行更深入的分析,复杂性应该已经可以减少到 O(log(n) * (r - l)) 左右。我会尝试向您发布解决方案,但请先确保您在此处提供了完整的问题描述!
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。