首页 > 其他 > 详细

2017百度之星复赛1003Pokémon GO------hdu6146

时间:2017-08-19 22:54:47      阅读:378      评论:0      收藏:0      [点我收藏+]

题目地址: http://acm.hdu.edu.cn/showproblem.php?pid=6146

分析:这道题有点麻烦啊!貌似是原题,讨论情况好恶心啊。

1、首先呢,我们考虑从左上角出发,先从左往右抓到底,再从右往左抓,因为题目要的是步数最少的,所以不能随便      走。每一步选择有2种可能,所以总的方案数是 b[i] = 2^i (i为列数)

2、我们可以第一列抓完,再抓第二列,也从左上角开始,到第二列有两种可能,到上面的格子和到下面的格子,所以

   方案数是  2 * a[i-1] (a[i-1]表示上一列的总方案数)

3、从左上角走,我们可以两列抓完再抓第三列,也就是两列的方案数是 2 * a[i-2],然后因为走到第三列可以上      下,也就是 *2 ,所以总的方案数是 4 * a[i-2] (如果抓完三列及以上再抓第四列(不与上面两种情况一样),    那么终点就不在第四列隔壁了,也就是步数不是最少)

前三点总结:从左上角抓的总方案数就是上面的方案数加起来,因为我们可以从四个角开始抓,所以方案数要乘以4

4、从中间开始抓(2~n-1列),那么我们可以先走左边,但是我们要最后回到这一列的下面,所以走左边只能走到底,再    走回来,也就是第1种情况,然后回到这一列之后,往右边走就可以随便了,所以这种情况是

   b[i-1]*a[n-i]*2*2,因为第i-1列可能从上下两位置开始,回来后往右边又可以上下两位置开始,所以乘以4。

   同理,右边也一样可推。而且开始第i列也可以上下两个格子开始,所以情况4总的方案数就是

   2*((b[i-1]*a[n-i]*4)+(b[n-i]*a[i-1]*4))

代码如下:

 

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL mod = 1000000007;
LL a[10005],b[10005];
int main() {
    int T;
    scanf("%d",&T);
    while(T--) {
        int n;
        scanf("%d",&n);
        b[1] = 1;
        for(int i = 2 ; i <= n; i++)
            b[i] = b[i - 1] * 2 % mod;
        //a[i]从左上角开始的方案数
        memset(a,0,sizeof(a));
        a[1] = 1; a[2] = 6;
        for(int i = 3 ; i <= n ; i++) {
            a[i] = (2 * a[i - 1]) % mod; // 第一列抓完再抓第二列
            a[i] = (a[i] + b[i]) % mod;  //从头到尾再从尾到头抓
            a[i] = (a[i] + 4 * a[i - 2] %mod) % mod;//两列抓完抓第三列
        }
        LL sum = a[n] * 4 % mod;//四个方向
        //统计其他的方法
        for(int i = 2 ; i < n; i++) {  //从中间开始往两边抓,开始那边只能从头到尾再到头抓
            sum = (sum + (((8 * b[i - 1])%mod * a[n - i]) % mod + ((8 * b[n - i])%mod * a[i - 1]) % mod) % mod)%mod;
        }
        if(n == 1) sum = 2;
        printf("%I64d\n",sum);
    }
    return 0;
}

 

2017百度之星复赛1003Pokémon GO------hdu6146

原文:http://www.cnblogs.com/maplefighting/p/7398123.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!