找到最大强度给定要在左右跳过的元素数量。请告诉我为啥我的代码对某些测试用例给出了错误的输出?
Posted
技术标签:
【中文标题】找到最大强度给定要在左右跳过的元素数量。请告诉我为啥我的代码对某些测试用例给出了错误的输出?【英文标题】:Find Maximum Strength given number of elements to be skipped on left and right.Please Tell me why my code gives wrong output for certain test cases?找到最大强度给定要在左右跳过的元素数量。请告诉我为什么我的代码对某些测试用例给出了错误的输出? 【发布时间】:2017-11-16 04:06:05 【问题描述】:给定一个包含“n”个项目的数组“s”,如果你有每个项目的左值“L[i]”和右值“R[i]”及其强度“S[i]”选择一个元素,你不能在它的左边选择 L[i] 元素,在它的右边选择 R[i],找到可能的最大强度。
示例输入:
5 //n
1 3 7 3 7 //strength
0 0 2 2 2 //Left Value
3 0 1 0 0 //Right Value
输出:
10
代码:
#include < bits / stdc++.h >
using namespace std;
unsigned long int getMax(int n, int * s, int * l, int * r)
unsigned long int dyn[n + 1] = ;
dyn[1] = s[1];
for (int i = 2; i <= n; i++)
dyn[i] = dyn[i - 1];
unsigned long int onInc = s[i];
int left = i - l[i] - 1;
if (left >= 1)
unsigned int k = left;
while ((k > 0) && ((r[k] + k) >= i))
k--;
if (k != 0)
if ((dyn[k] + s[i]) > dyn[i])
onInc = dyn[k] + s[i];
dyn[i] = (dyn[i] > onInc) ? dyn[i] : onInc;
return dyn[n];
int main()
int n;
cin >> n;
int s[n + 1] = , l[n + 1] = , r[n + 1] = ;
for (int i = 1; i <= n; i++)
cin >> s[i];
for (int i = 1; i <= n; i++)
cin >> l[i];
for (int i = 1; i <= n; i++)
cin >> r[i];
cout << getMax(n, s, l, r) << endl;
return 0;
【问题讨论】:
【参考方案1】:您的方法存在问题:
在您的 DP 表中,您存储的信息大约是迄今为止最大的可能。有关是否已考虑 ith
索引的信息将丢失。 仅当任何先前看到的指数不在范围内或在范围内但未被考虑时,您才可以考虑在当前指数上加强以扩展先前的指数。
解决方案:
重新配置您的 DP 重复周期。如果考虑了ith
索引,则让DP[i]
表示最大答案。现在您只需要扩展满足范围条件的那些。答案是所有 DP 指数的最大值。
代码:
vector<long> DP(n,0);
DP[0]=strength[0]; // base condition
for(int i = 1; i < n ; i++)
DP[i] = strength[i];
for(int j = 0; j < i ; j++)
if(j >= (i-l[i]) || i <= (j+r[j])) // can't extend
else
DP[i]=max(DP[i],strength[i]+DP[j]); // extend to maximize result
long ans=*max_element(DP.begin(),DP.end());
时间复杂度: O(n^2)
可能的优化:
有更好的方法来计算您可能想要研究的最大值。您可以先查看Segment tree 和Binary Indexed Trees。
【讨论】:
乐于助人...如果我的回答对您有帮助,您可以接受。如果您还有任何疑问,可以提问,以便我可以编辑我的答案以清除它。以上是关于找到最大强度给定要在左右跳过的元素数量。请告诉我为啥我的代码对某些测试用例给出了错误的输出?的主要内容,如果未能解决你的问题,请参考以下文章