在不使用图形的情况下,以最少的产品从第一个索引到达最后一个?

牧马人

在codechef上解决此问题

在拜访了一个儿时的朋友之后,厨师想回到他的家。朋友住在第一条街,而厨师本人则住在第N条(也是最后一条)街。他们的城市有点特殊:当且仅当1 <= Y-X <= K,并且其中K是提供给您的整数值时,您才可以从X街移至Y街。厨师要以这样一种方式回家:所有访问过的街道的特殊号码的乘积最小(包括第一条和第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来解决它我的方法:

  1. 取一个数组并计算最小乘积以达到每个索引,并将其存储在相应的索引中。
  2. 可以使用自上而下的方法并递归发送索引(符合条件),直到到达起始索引,然后进行计算。
  3. 在所有计算出的值中,存储最小值。
  4. 如果已经计算返回,则进行其他计算。

代码:

 #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;
}

已经两天了,我检查了每个极端的情况和限制条件,但仍然给出错误的答案!解决方案出了什么问题?

需要帮忙。

法尔登

分析

有很多问题。这是我发现的:

  1. 100009无缘无故地将产品的价值限制在较低的水平乘积可能会更高(这确实是问题仅要求取模值的原因1000000007
  2. 您限制其街道差你的动作special numberK,而问题的声明说,你可以任何其城市之间移动index的差异不如K
  3. 在动态编程功能中,您可以计算乘积并存储乘积的模数。这可能导致问题,因为大数的模可以低于小数的模。这可能会破坏以后的计算。
  4. 您使用的整数类型long int太短。
  5. 您的算法复杂度太高。

从所有这些问题来看,最后一个是最严重的。我通过更改整个方法并使用更好的数据结构来解决此问题。

第一个问题

在您的main()职能中:

if(dp[n-1]==MAX)
   printf("0");

在您的cal()职能中:

LI minn=MAX;

您应将此行替换为:

LI minn = std::numeric_limits<LI>::max();

不要忘记:

#include <limits>

第二个问题

   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--)

并完全删除特殊数字上的条件。

第三题

您正在寻找特殊数字乘积最低的路径。在当前设置中,您在对乘积取模比较路径的乘积。这是错误的,因为更高的模数可能会变得很低(例如,其乘积为1000000008模的路径将具有模的模数,1并且即使有一个乘积为的路径,您也将选择此路径2)。

这意味着您应该比较真实的产品,而不用取它们的模。这些产品的价格可能会很高,因此您应该采用对数。这将使您可以将产品与简单产品进行比较double请记住:

log(a*b) = log(a) + log(b)

第四题

使用unsigned long long

第五题

我解决了所有这些问题,并提交了Codechef CHRL4。除了一个测试用例,我都接受了。无法接受的测试用例是因为超时。这是由于您的算法的复杂度为O(k*n)

您可以O(n)使用自下而上的动态编程方法(而不是自上而下)并使用将返回k先前街道的最小日志值的数据结构来实现复杂性您可以查找sliding window minimum algorithm以查找操作方法。

参考

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

在不使用Java的情况下删除数组的第一个元素

如何在不使用任何API方法的情况下查找字符串的第一个字符

在不知道索引的情况下获取Series的第一个元素

在不知道索引的情况下获取Series的第一个元素

如何在不使用foreach循环的情况下获取JObject的第一个孩子

为什么在多重继承的情况下QObject需要成为第一个

默认情况下从选择框中选择第一个值-AngularJS

仅显示产品分类的第一个和最后一个术语

在不使用双COM的情况下将第一个数组的元素复制到第二个

在Python中:如何在情况下的第一个位置处理零

Python熊猫获得数据的第一个和最后一个索引,如果第一个也是最后一个,则重复

在没有第一个和最后一个元素的情况下循环字典

如何在不使用模块的情况下根据单词的第一个字符拆分列表并将其放入字典中?

在不使用list的情况下,从Python中的字典中检索第一个键值对,迭代

在不使用shift()方法的情况下删除数组中的第一个元素

在不使用循环或变量的情况下从一个月的最后一天获取数据

在不知道键的情况下打印第一个值

在不使用GetParent()的情况下修剪最后一个目录/文件夹

保留数组的第一个索引元素和最后一个索引元素

如何从第二个位置索引到最后一个到第一个位置?

如何在r中不使用NA的情况下选择第一个和最后一个测试

如何在不使用多个parent()调用的情况下找到(元素表的)第一个祖先?

如何在不修改第一个变量的情况下使用Fluent

如何在不使用.indexOf()的情况下检查当前url是否大于数组中的第一个url

如何在不使用 reverse() 函数的情况下反转字符串,希望反转不是从最后一个索引到 swift 的第一个索引逐字逐句

最后打印第一个变量(索引=0)

在这种情况下如何选择第一个孩子?

链表不打印的第一个元素在特殊情况下

在不使用列表的情况下获取最后一个字母值