在不使用图形的情况下,以最小的乘积从第一个索引到最后一个索引
Reaching from first index to last with minimum product without using Graphs?
在编解码上解决这个问题:
在拜访了一个儿时的朋友后,大厨想回到他的家。朋友住在第一条街,大厨自己住在第n街(最后一条)街。他们的城市有点特别:你可以从那里搬走从X街到Y街当且仅当1 <= Y- X <= K,其中K是给定的整数值。大厨想要以这样一种方式回家,所有参观过的街道的产物特殊号码是最少的(包括第1街和第n街)。请帮他找到这样的产品。输入
第一行输入由两个整数N和K组成分别为街道数和K值。第二行由N个数字组成- A1, A2,…分别为AN,其中Ai等于到第i街的特殊号码。输出
请输出最小可能积的值,取模1000000007. 约束
1≤N≤10^5 1≤Ai≤10^5 1≤K≤N示例
输入:4 2 1 2 3 4.
输出:8
可以根据本教程使用图形来解决我试图解决它不使用图,只是使用递归和DP。我的方法:
- 取一个数组,计算到达每个索引的最小积,并将其存储在相应的索引中。
- 可以使用自顶向下的方法,递归地发送索引(合格),直到到达起始索引。
- 在所有计算值中存储最小值。
- 如果它已经计算过,返回它,否则计算。
#include<iostream>
#include<cstdio>
#define LI long int
#define MAX 100009
#define MOD 1000000007
using namespace std;
LI dp[MAX]={0};
LI ar[MAX],k,orig;
void cal(LI n)
{
if(n==0)
return;
if(dp[n]!=0)
return;
LI minn=MAX;
for(LI i=n-1;i>=0;i--)
{
if(ar[n]-ar[i]<=k && ar[n]-ar[i]>=1)
{
cal(i);
minn=(min(dp[i]*ar[n],minn))%MOD;
}
}
dp[n]=minn%MOD;
return;
}
int main()
{
LI n,i;
scanf("%ld %ld",&n,&k);
orig=n;
for(i=0;i<n;i++)
scanf("%ld",&ar[i]);
dp[0]=ar[0];
cal(n-1);
if(dp[n-1]==MAX)
printf("0");
else printf("%ld",dp[n-1]);
return 0;
}
已经2天了,我检查了每一个角落的情况和约束,但它仍然给出错误的答案!解决方案有什么问题?
需要帮助。
分析
有很多问题。以下是我的发现:
- 你们毫无理由地将产品限制为低于
100009
的值。产品可以比这高得多(这确实是问题只要求值模1000000007
的原因) - 你限制你在
special number
差值为K
的街道上移动,而问题说明说你可以在index
差值小于K
的任何城市之间移动 - 在动态规划函数中,计算乘积并存储乘积的模。这可能会导致一个问题,因为一个大数字的模可能比一个小数字的模要小。这可能破坏以后的计算。
- 您使用的整型
long int
太短 你的算法复杂度太高。
1的问题
在你的main()
函数中:
if(dp[n-1]==MAX)
printf("0");
在你的cal()
函数中:
LI minn=MAX;
你应该将这一行替换为:
LI minn = std::numeric_limits<LI>::max();
不要忘记:
#include <limits>
<<p> 第二问题/strong> for(LI i=n-1;i>=0;i--)
{
if(ar[n]-ar[i]<=k && ar[n]-ar[i]>=1)
{
. . .
}
}
你应该替换for循环条件:
for(LI i=n-1;i>=n-k;i--)
并去掉特殊数的条件。
3
您正在寻找特殊数乘积最小的路径。在当前设置中,在
取乘积的模后比较path的乘积。这是错误的,因为较高的数的模可能会变得非常低(例如,一个路径的乘积是1000000008
,它的模是1
,你会选择这个路径,即使有一个路径的乘积只有2
)。
这意味着你应该比较真实的产品,而不是取它们的模。当这些乘积变得很大时,你应该取它们的对数。这将允许您使用简单的double
来比较产品。记住:
log(a*b) = log(a) + log(b)
<<p> 第四问题/strong> 使用unsigned long long
我修复了所有这些问题并提交了codechef CHRL4。除了一个测试用例外,我接受了所有测试用例。测试用例未被接受是因为超时。这是因为你的算法的复杂度达到了O(k*n)
。
您可以使用自下而上的动态规划方法来实现O(n)
复杂度,而不是使用自上而下的数据结构,该数据结构将返回k
先前街道的最小日志值。您可以查看sliding window minimum algorithm
查看如何操作。
引用
- numeric_limits: max ()
- 我自己的编解码CHRL4解决方案:自下而上dp +滑动窗口最小值
- 为什么它只打印双链接列表的第一个值,而我的程序却崩溃了
- std::find,返回所有找到的值的替代方法,而不仅仅是存在重复的向量的第一个值
- 如何仅读取文本文件中的第一个值
- 在C++中,如何在第一个"system()"结束后执行第二个"system()"?
- 查找不在标准中的第一个值::设置<int>最小-最大值
- C++:忽略第一个 cin.ignore 之后的输入
- 在C++中打印多个矢量的第一个值
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- C++第一个cout将不会打印
- 我们可以在第一个else-if条件结束后使用另一个else-if条件吗
- OpenGL:第二个VBO破坏了第一个VBO
- 为什么第一个Dynamic_cast没有投射到基类?
- 如何用索引命名一个变量来存储输入 mxArray?
- OpenGL 2D游戏只绘制第二个精灵纹理而不是第一个
- C++ 为什么程序只读取第一个值
- 在我的第一个C++程序中需要一些帮助(简单)
- 为什么我的代码在第一个 if 语句处中断?
- 是否可以从另一个类对象调用一个类函数而不继承第一个类
- 无法使我的第一个Windows OpenGL窗口抬起并运行
- 将参数初始化为构造函数,而不是第一个