• Codeforces 407B Long Path(好题 DP+思维)


    题目链接:http://codeforces.com/problemset/problem/407/B

    题目大意:
    一共n+1个房间,一个人从1走到n+1,每次经过房间都会留下一个标记,每个房间有两扇门:
    ①第一扇门通向i+1,如果当前房间标记有奇数个,则必须走第一扇门。
    ②第二扇门通向pi(pi<=i),如果当前房间标记有偶数个,则必须走第二扇门。
    问从房间1走到房间n+1需要多少步,结果对1e9+7取模。
    解题思路:
    之前傻了。。。明明都推出规律了,结果被自己给否定了。。。
    设dp[i]表示从1~i需要走多少步,那么我们可以得到状态转移方程:
    dp[i+1]=dp[i]+dp[i]-dp[p[i]]+2=2*dp[i]-dp[p[i]]+2
    下面来解释一下,如果当前走到了i点,那么i点之前的所有点的标记数肯定都是偶数,因为只有标记为偶数才能往后走。
    偶数可以看成是0,相当于跟第一次走一样。这里的2是因为从i到p[i]需要一步,从i到i+1需要一步。
    从1~i为的步数为dp[i],然后返回p[i],从p[i]~i的步数为dp[i]-dp[p[i]],所以总步数就是dp[i]+dp[i]-dp[p[i]]+2=2*dp[i]-dp[p[i]]+2。

    代码

     1 #include<bits/stdc++.h>
     2 #define lc(a) (a<<1)
     3 #define rc(a) (a<<1|1)
     4 #define MID(a,b) ((a+b)>>1)
     5 #define fin(name)  freopen(name,"r",stdin)
     6 #define fout(name) freopen(name,"w",stdout)
     7 #define clr(arr,val) memset(arr,val,sizeof(arr))
     8 #define _for(i,start,end) for(int i=start;i<=end;i++)
     9 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
    10 using namespace std;
    11 typedef long long LL;
    12 const int N=1e5+5;
    13 const int MOD=1e9+7;
    14 const int INF=0x3f3f3f3f;
    15 const double eps=1e-10;
    16 
    17 LL dp[N];
    18 int p[N];
    19 
    20 int main(){
    21     FAST_IO;
    22     int n;
    23     cin>>n;
    24     for(int i=1;i<=n;i++){
    25         cin>>p[i];
    26     }
    27     for(int i=1;i<=n;i++){
    28         dp[i+1]=(2*dp[i]-dp[p[i]]+2+MOD)%MOD;
    29     }
    30     cout<<dp[n+1]<<endl;
    31     return 0;
    32 }
  • 相关阅读:
    Use MVS Dsbame convensions. windows下ftp.exe客户端上传错误
    Sqlserver 2005:数据库快照
    Oracle:使用ASM自动存储管理, 严重推荐
    Thunderbird 邮件客户端:windows 和 ubuntu 或 liunx 下共用的方法
    Oracle:Oracle 10 RAC 安装群集件的准备工作
    SSH
    STL
    ASP生成静态Html文件技术杂谈
    Nessus:网络和主机漏洞评估程序安装试用
    table 的 id 属性不被 document.getElementById支持
  • 原文地址:https://www.cnblogs.com/fu3638/p/9892279.html
Copyright © 2020-2023  润新知