您的位置:首页 > 其它

递归加一些思考(钥匙计数之二)

2017-08-14 17:35 197 查看
题目:http://172.22.164.136:8080/vjudge/contest/view.action?cid=37#problem/F

F - 钥匙计数之二

Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u

Description

一把钥匙有N个槽,2

思路:

本题很难想到用递归去做,并且除了递归还需要想清楚一些特殊的东西。

1. 当n-1是钥匙的时候,则考虑他n-1位是不是1或者6.那么是a
+=a[n-1]*5,如果不是那么就要a
=a[n-1]*6.所以,要定义一个数组将n-1的时候。以6或者1 结尾的要存起来。

2. 当n-1不是钥匙的时候,那么只有前面n-1是有2个不同的深度组成,同时避免,1和6相连。所以这里的情况我分四种情况。

(1)当前面没有1或者6的时候并且最后一位不是1或者6的时候。那么就是C(4,2)*(pow(2,i-1)-2)*2;

(2)当前面没有1或者6的时候,最后一位是 1或者6的时候,用其他数组将他存起来。为C(4,2)*(pow(2,i-1)-2)*2;

(3)当前面有1或者6的时候。最后一位不是1或者6的时候。为4*2*(pow(2,i-1)-2)*3

(4)当前面有1或者6的时候,最后一位是1或者6 的时候。这个时候,就要考虑前面n-2位了。既n-1位一定你选的那2个数中不是1或者6 的那个数,这样最后一位才会是1或者6.此时情况位4*2*(pow(2,i-2)-1)。注意这里是减1.不是减2。因为全面n-2位全为1111是可以的。要想清楚哦。

(虽然自己前面写的可能不清楚,但是看代码就知道了)

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
int main(){
__int64 s[26];//总的个数
__int64 a[26];//以1或者6结尾的
int i;
s[3]=104;
a[3]=32;
for(i=4;i<26;i++){
s[i]=a[i-1]*5+(s[i-1]-a[i-1])*6;//如果前n-1是钥匙
s[i]+=6*((__int64)pow(2,i-1)-2)*2;//前n-1不是钥匙,并且这n-1里面没有选1或者6.第n项也没有选1或者6
a[i]=6*((__int64)pow(2,i-1)-2)*2;//如果前n-1项没有选了1或者6.第n项有1或者6
s[i]+=2*4*((__int64)pow(2,i-1)-2)*3;//如果前面n-1选了1或者6其中一个.第n项没有选
a[i]+=2*4*((__int64)pow(2,i-2)-1);//如果前面n-1项选了1或者6,第n个没有选的话。
s[i]+=a[i];

a[i]+=(s[i-1]-a[i-1])*2+a[i-1];//合格里面。以1或者6结尾的
}
for(i=3;i<26;i++)
cout<<'N'<<'='<<i<<':'<<' '<<s[i]<<endl;
return 0;
}


(还有一个类似的题目,更这个是相反的 2017暑假集训16级-递推 - Virtual Judge

http://172.22.164.136:8080/vjudge/contest/view.action?cid=37#problem/C 可以值得做的)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: