头条2018附加题

https://www.nowcoder.com/practice/58b04ed2865f4ff4921290f1bd4ee486?tpId=90&tqId=30811&tPage=2&rp=2&ru=%2Fta%2F2018test&qru=%2Fta%2F2018test%2Fquestion-ranking

题目描述

存在n+1个房间,每个房间依次为房间1 2 3...i,每个房间都存在一个传送门,i房间的传送门可以把人传送到房间pi(1<=pi<=i),现在路人甲从房间1开始出发(当前房间1即第一次访问),每次移动他有两种移动策略:
    A. 如果访问过当前房间 i 偶数次,那么下一次移动到房间i+1;
    B. 如果访问过当前房间 i 奇数次,那么移动到房间pi;
现在路人甲想知道移动到房间n+1一共需要多少次移动;

思路

主要在于理解题意,1<=pi<=i这个条件表明,前面所有的房间都进去偶数次了,因为奇数次的话只能往前走。

dp[i]表示从都一个房间达到第i个房间且为偶数次的移动次数

如果要到达第i个房间,那么第i-1个房间一定是偶数次达到

dp[i]=dp[i-1]+1;

第一次到达第i个房间是第奇数次,所以这一次一定往前移动到第pi的房间 dp[i]+=1

到达pi号房间这个时候一定是奇数次,那么肯定从当前位置一顿操作达到第pi-1号房间,且到达pi-1号房间次数为偶数次,这个时候才可能往后到达pi号房间且为偶数次

那么从第pi号房间(偶数次)到达i-1号房间(偶数次)offset=dp[i-1]-dp[pi-1]-1(这里就是pi,没有写错,只不过这里有个中间过渡,从pi奇次到pi-1偶次一顿操作,这个操作在到达i-1号偶数次的过程中也经历过一遍,所以互相相减就抵消了,但是这里多了一个pi-1偶数次到pi偶数次所以需要减一)

最后从i-1偶次到达i偶次dp[i]+=1

最后结果

dp[i]=dp[i-1]+1+1+dp[i-1]-dp[pi-1]-1+1=2*dp[i-1]-dp[pi-1]+2;

public static void main(String[] args) {    
        Scanner in = new Scanner(System.in);
        long mod = 1000000007;
        int n = in.nextInt();
        long[] dp = new long [n+1];
        int[] pi = new int[n+1];
        for(int i = 1; i < n+1;i++){
            pi[i] = in.nextInt();
        }
        for(int j = 1; j < n+1; j++){
            dp[j] = (2 * dp[j-1]%mod - dp[pi[j]-1] + 2) % mod;
        }
        System.out.println(dp[n]);
}

 

posted @ 2019-05-19 11:58  LeeJuly  阅读(388)  评论(0)    收藏  举报