纪中23日c组T3 2161. 【2017.7.11普及】围攻

2161. 围攻

(File IO): input:siege.in output:siege.out

时间限制: 1000 ms  空间限制: 262144 KB  具体限制

Goto ProblemSet

题目描述

经过刘邦的严密缉查,项羽的位置也就水落石出了。刘邦便趁机集合军队,进行对项羽的围攻。为了增加胜率,张良研究出一种全新的战法,目的就是一举打败难缠的项羽。
  这种军队共有N个单位,一个接着一个排成一排,每个单位可以是士兵,或者是战车,这样的组合可以爆发出意想不到的强大战斗力;但有一点,两辆战车不能相邻,否则会发生剐蹭等不好的事故。刘邦希望知道这N个单位的军队都多少种不同的排列方法,以便在战场中随机应变。两种军队的排列方法是不同的,当且仅当某一个单位对应不同,如:第i位这种是士兵,那种是战车……

输入

输入仅一行,一个整数N。

输出

输出仅一行,一个整数,表示排列的方案数。
 答案对 10^8+7 取模

样例输入

3

样例输出

5

数据范围限制

对于30%的数据:N≤15;
  对于70%的数据:N≤10^6;
  对于100%的数据:N≤10^18。

提示

样例解释

以0表示士兵,1表示战车,则全部方案如下:000,100,010,001,101。

Solution

这道题是什么题?组合?数列?暴力枚举?搜索剪枝?

先打个表压压惊……

Algorithm1

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<map>
#include<set>
#include<queue>
#include<vector>
#define IL inline
#define re register
using namespace std;

long long n,ans;
IL void dfs(int depth,bool last)
{
    if(depth>=n) {
        ans++;
        return;
    }
    if(!last) dfs(depth+1,1);
    dfs(depth+1,0);
}
int main()
{
//    freopen("siege.in","r",stdin);
//    freopen("siege_table.out","w",stdout);
    for(n=1;n<=50;n++)
    {
        cout<<"n="<<n<<endl;
        ans=0;
        dfs(0,0);
        cout<<ans<<endl;
    }
    return 0;
}

table

打表找规律,暴力出奇迹

n=1
2
n=2
3
n=3
5
n=4
8
n=5
13
n=6
21
n=7
34
n=8
55
n=9
89
n=10
144
n=11
233
n=12
377
n=13
610
n=14
987
n=15
1597
n=16
2584
n=17
4181
n=18
6765
n=19
10946
n=20
17711
n=21
28657
n=22
46368
n=23
75025
n=24
121393
n=25
196418
n=26
317811
n=27
514229
n=28
832040
n=29
1346269
n=30
2178309
n=31
3524578
n=32
5702887
n=33
9227465
n=34
14930352
n=35
24157817
n=36
39088169
n=37
63245986
n=38
102334155
n=39
165580141
//速度太慢了,后略……

好了,规律已找到,就是从2:1开始的斐波那契数列嘛

(然而我并没有看到取模,于是在打完表后我就去写高精度了)

证明呢?

别问我……下午听完讲后再证明吧……

Algorithm2

当然是:

暴力递推,边算边取模!

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define IL inline
11 #define re register
12 using namespace std;
13
14
15 int main()
16 {
17 //    freopen("siege.in","r",stdin);
18 //    freopen("siege.out","w",stdout);
19     re unsigned int n,x=2,y=1,t,mo=1e8+7;
20     cin>>n;
21     while(--n)
22     {
23         t=x;
24         x=x+y;
25         y=t;
26         while(x>=mo)
27             x-=mo;
28     }
29     printf("%d",x);
30     return 0;
31 }

经过我多次实验,

while+减法比%要快一倍

register+局部变量比无register的全局变量也要快一点点

每次只需要让x取模

y和t也会变小

以及

这还是拿不到100分!

Algorithm3

好吧……我之前在洛谷上做过这道题的算法版(只是没有这些背景)

然而,我忘记了……

洛谷P1962 斐波那契数列

对于100%的数据,n<=10^18,一些公式可以利用

公式一

f(2n)=f(n)^2-f(n-1)^2=(2f(n-1)+f(n))*f(n)

公式二

f(2n+1)=f(n+1)^2+f(n)^2

证明

下午再说……

这样的话,只要对n进行二进制运算就可以了O(log(n))

顺便加一个数组存已经计算好的斐波那契数,方便以后调用

(不过10^18貌似存不下,考虑使用map)

Code3

 1 #include<iostream>
 2 #include<algorithm>
 3 #include<cstdio>
 4 #include<cstring>
 5 #include<cmath>
 6 #include<map>
 7 #include<set>
 8 #include<queue>
 9 #include<vector>
10 #define IL inline
11 #define re register
12 using namespace std;
13 map<int,int>fbnq;
14 long long mo=1e8+7;
15 IL long long f(long long num)
16 {
17     if(num==1) return 1;
18     if(num==2) return 1;
19     if(num==3) return 2;
20     if(fbnq.find(num)!=fbnq.end()) return fbnq[num];
21     long long ans=0,n=num>>1;
22     if(num&1)
23     {
24         ans=f(n+1)*f(n+1)%mo;
25         ans+=f(n)*f(n)%mo;
26     }
27     else
28     {
29         ans=2*(f(n-1))%mo+f(n);
30         ans%=mo;
31         ans*=f(n);
32
33     }
34     ans%=mo;
35     fbnq[num]=ans;
36     return ans;
37 }
38 int main()
39 {
40 //    freopen("siege.in","r",stdin);
41 //    freopen("siege.out","w",stdout);
42     long long n;
43     cin>>n;
44     printf("%lld",f(n+2));
45     return 0;
46 }

Attention

最好都开long long以防还没取模就溢出了!

还有许多细节可以优化

但是我饿了

纪中2019-08-23 12:32:06

哎……

原文地址:https://www.cnblogs.com/send-off-a-friend/p/11399227.html

时间: 2024-10-02 10:04:57

纪中23日c组T3 2161. 【2017.7.11普及】围攻的相关文章

纪中20日c组T2 2122. 【2016-12-31普及组模拟】幸运票

2122. 幸运票 (File IO): input:tickets.in output:tickets.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto ProblemSet 题目描述 给你一个数N(1<=N<=50),每张票有2N位,同时给你这2N位上的和S,如果这张票的前N位的和等于后N位的和,那我们称这张票是吉祥的,每一位可以取0-9. 你的任务是计算吉祥票的总数. 输入 输入N和S,S是所以位上的和,假设S<=1000 输出 输出吉祥票

纪中10日T1 2313. 动态仙人掌

纪中10日 2313. 动态仙人掌 (File IO): input:dinosaur.in output:dinosaur.out 时间限制: 1500 ms  空间限制: 524288 KB  具体限制 Goto ProblemSet 题目描述 沙雕游戏……反正我没玩过…… 输入 输出 样例输入 数据范围限制 Solution 考试时想的是对的 为什么就是没有分呢? 首先看看仙人掌有几种情况 situation1 两个比较分开的仙人掌…… 小恐龙按照这样走(跳),并没有什么特殊操作.这时的最

纪中17日T1 2321. 方程

纪中17日T1 2321. 方程 (File IO): input:cti.in output:cti.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 Goto ProblemSet 题目描述 输入 输出 样例输入 样例输出 数据范围限制 提示 吐槽 这些图片太模糊了吧…… 还有那吓人的 mod 998244353 都使得我们对这道题的恐惧感叠加了998244353层…… 没想到……只有三种答案!(三进制呵呵哒) Solution (约定:用line[i]表示第

纪中10日T1 2300. 【noip普及组第一题】模板题

2300. [noip普及组第一题]模板题 (File IO): input:template.in output:template.out 时间限制: 1000 ms  空间限制: 262144 KB  具体限制 题目描述 输入 输出 样例输入 样例输出 数据范围限制 朴素算法 考试开始的前一个小时我一直在折腾朴素算法 -> 对拍 1 #pragma GCC optimize(2) 2 #include<bits/stdc++.h> 3 #define IL inline 4 usin

纪中5日T3 1566. 幸运锁(lucky.pas/c/cpp)

1566. 幸运锁(lucky.pas/c/cpp) 题目描述 有一把幸运锁,打开它将会给你带来好运,但开锁时需要输入一个正整数(没有前导0).幸运锁有一种运算,对于一个正整数,返回他的相邻两位数字间的差,如1135,运算结果为22(会去掉前导0). 现在已知只有经过反复运算最终结果为7的数才能打开这把锁,给你一个区间[a,b],问该区间中有多少个能打开幸运锁的幸运数. 输入 第一行两个整数a,b. 输出 一个整数K,表示共有多少个这样的数. 样例输入 1 10 样例输出 1 数据范围限制 [限

纪中10日T3 2296. 神殿 bfs

原文地址:https://www.cnblogs.com/send-off-a-friend/p/11330414.html

纪中……结束了……

纪中25日 纪中二十多天的生活,就这样结束了. 带着没有离开c组的遗憾,结束了. 算是日久生情吧,中山纪念学校,于我而言,已经成为了一段无法忘记的记忆. 但是……仅仅只能一遍又一遍的回忆了. 科学馆三层楼的机房,是我们一起学习的地方,有说笑,有模拟赛:有爆零,有AK. 最重要的还是,大家都在一起,有陪伴吧. 同来望月人何处,风影依稀似去年. 原文地址:https://www.cnblogs.com/send-off-a-friend/p/11407424.html

七周二次课(1月23日) 10.6 监控io性能 10.7 free命令 10.8 ps命令 10.9 查看网络状态 10.10 linux下抓包

七周二次课(1月23日)10.6 监控io性能10.7 free命令10.8 ps命令10.9 查看网络状态10.10 linux下抓包 =====================================================================================================================================================================================

软考中高项学员:2016年3月23日作业

软考中高项学员:2016年3月23日作业 一.项目进度管理1.进度管理包括哪六个过程?2.什么是滚动式规划?3.什么是控制账户.规划组合?4.请说明FS.FF.SS.SF的含义.5.虚活动的含义?6.三种依赖关系是哪三种?7.活动资源估算的方法.工具和技术?(记)8.活动历时估算的方法.工具和技术?(记)9.何时可以用类比估算?10.参数估算的含义?11.三点估算公式?标准差计算公式?正负一倍的标准差情况下,概率是多少?2倍的呢?3倍的呢?12.后备分析中,应急时间=时间储备=缓冲时间吗?13.