记录一个菜逼的成长。。
题目链接
题目大意:
给你n个数,
ai∈[1,n]
q
个查询,每次给你
有操作:
问经过多少次这样的操作,使得
p>n
一开始我是记忆化搜索,
然而提交运行与本地运行不一致???第二次碰到这个问题,完全不知道什么原因。
爆栈?怎么样例就爆。。
提交运行:
本地运行:
—————–分割———————
dp[p][k]
:= 表示要使p大于n的次数
有如下状态转移:
如果
i+a[i]+k<=n
dp[i][j]=dp[i+a[i]+k][j]+1
否则
dp[i][j]=1
#include <cstdio>
#include <utility>
#include <map>
using namespace std;
#define mp make_pair
typedef pair<int,int> PII;
const int maxn = 100000 + 10;
int a[maxn],n;
int dp[maxn][330];
//原先的记忆化搜索。。不知道什么错使得提交运行与本地运行不一致
int dfs(int p,int k)
{
if(p > n)return 0;
if(dp[p][k])return dp[p][k];
dp[p][k] = dfs(p + a[p] + k,k) + 1;
}
int main()
{
while(~scanf("%d",&n)){
int q;
for( int i = 1; i <= n; i++ )
scanf("%d",a+i);
for( int i = 1; i < 330; i++ ){
for( int j = n; j > 0; j-- ){
int t = j + a[j] + i;
if(t > n)dp[j][i] = 1;
else dp[j][i] = dp[t][i] + 1;
}
}
scanf("%d",&q);
while(q--){
int p,k;
scanf("%d%d",&p,&k);
if(k < 330){
printf("%d\n",dp[p][k]);
continue;
}
int ans = 0;
while(p <= n){
ans++;
p = p + a[p] + k;
}
printf("%d\n",ans);
}
}
return 0;
}

本文介绍了一个使用动态规划解决特定循环问题的方法。面对一系列数值和查询条件,如何通过递归及状态转移方程来求解最小操作次数,最终使得初始位置超出预设范围。文章详细解释了算法的设计思路,并附带完整的C++实现代码。

被折叠的 条评论
为什么被折叠?



