您的位置:首页 > 其它

CodeForces 407B Long Path ( DP )

2015-10-26 23:31 369 查看


题目大意:

有n+1个房间。从1-n个房间。每个房间有两扇门。一扇去i+1的房间另一扇去编号为pi的房间。问到达n+1的房间至少要走多少次


思路:

如果我没看美辰巨巨的博客。我也以为会是模拟。结果是DP。那我猜想应该是把到达下一个房间所需要的步数 + 前一次到达当前房间的步数

那么问题来了。DP数组应该怎么存放。

参考美辰巨巨的办法。DP存放的是从当前位置到达下一位置所需要的步数。然后在把DP数组走一遍即可以求出答案

另一种思路一直看不懂,被注释掉的部分

思路: 首先一个思考方法就是对比较小的样例进行纸上演算,了解题目的规律,看清本质。

不放p[i]=1;  i=1,2,3,4,5;

然后就发现每次都艰难的到了某一个点,又回到1,“无功而返”。

但是,找到了一些规律,每次第一次到达某一个点的时候,前面的全部是0(0-偶数,1-奇数),然后即将直接跳回到pi这个点,count(pi)==奇数。 然后又会历尽千辛万苦到了i,只是这一次,count(i)==偶数了,可以往前走了。

那么记f(i)代表第一次到i号结点的时候走的步数。 那么f(i+1)=f(i)+1(走到pi)+重新回到i的步数+1(向前走一步到i+1),重新回到i的步数,由于1,2,3...i-1,这些结点的count属性,和第一次到pi的时候是一样的,那么重新回到i的步数==f(i)-f(p[i]) .

然后地推公式就是f(i+1)=2*f(i)+2-f(p[i])  ,dp即可。

// Created by Chenhongwei in 2015.
// Copyright (c) 2015 Chenhongwei. All rights reserved.

#include "iostream"
#include "cstdio"
#include "cstdlib"
#include "cstring"
#include "climits"
#include "queue"
#include "cmath"
#include "map"
#include "set"
#include "stack"
#include "vector"
#include "sstream"
#include "algorithm"
using namespace std;
const int inf=1e8;
const int maxn=1e5;
const int mod=1e9+7;
typedef long long ll;
typedef unsigned long long ull;
long long n,p[1010];
long long dp[1010];
int main()
{
//ios::sync_with_stdio(false);
// freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
// cin>>n;
// dp[1]=0;
// for(int i=1;i<=n;i++)
// {
// cin>>p[i];
// dp[i+1]=(2*dp[i]-dp[p[i]]+2+mod)%mod;
// }
// cout<<dp[n+1]<<endl;
cin>>n;
for(int i=1;i<=n;i++)
cin>>p[i];
dp[0]=0;
for(int i=1;i<=n;i++)
{
dp[i]=2;
for(int j=p[i];j<i;j++)
dp[i]=(dp[i]+dp[j])%mod;
}
ll ans=0;
for(int i=1;i<=n;i++)
ans=(ans+dp[i])%mod;
cout<<ans<<endl;
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: