码迷,mamicode.com
首页 > 其他好文 > 详细

真的猛士,敢于开数学!!!!!

时间:2019-03-27 12:48:06      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:pac   bit   from   i++   计数   长度   组合数   安全   use   

dp专题看得差不多了,本来是想看图论,

但是那天物理课,莫名打开了数学专题

看了一半也不太好,就先看完再说吧~

数学专题不用markdown好难写啊

1.组合数学

UVa580

题意:一个长度为n的序列(n<=30),由若干U,L组成

有大于等于3个连续的U的序列则为危险序列

求危险序列的数量

方法一:(LRJ)

f(n)=(1<<n-3) + sigma ( g(i-2)*(1<<(n-i-2) )    (i from 2 to n-2)
g(i)=(1<<i)-f(i)

 

g表示长度为i的安全序列的个数 

因为题目的要求是最少三个U,那么则假设第i,i+1,i+2,位置放置的U使序列“由安全变成危险

也就是说,希望第i个位置的U起决定性作用

那么为了防止前面已经有序列起到决定性作用,我们使第i-1个一定为L

---->对于第i个位置,有g(i-2)*(1<<(n-i-2))

---->前i-2个没有危险序列的个数 * 第(i+3~n)个任意排列

 式子里面的 (1<<n-3)指的是i==1的情况

因为求和是从i==2开始的

f[0]=f[1]=0=f[2]=0;

g[0]=1,g[1]=2,g[2]=4;

 

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[40], g[40];
 4 int main(){
 5     f[0] = f[1] = f[2] = 0;
 6     g[0] = 1, g[1] = 2, g[2] = 4;
 7     for (int i = 3; i <= 35;i++){
 8         f[i] = (1 << (i - 3));
 9         for (int j = 2; j <= i-2;j++){
10             f[i] += g[j - 2] * (1 << (i - j - 2));
11         }
12         g[i] = (1 << i) - f[i];
13     }
14     int n;
15     while(cin>>n&&n){
16         cout << f[n] << endl;
17     }
18     system("pause");
19     return 0;
20 }

方法二:

  dp[i]表示第i位为L结尾的序列数量:

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

  对于第i-1个位置   我们想要放置U,但是序列不危险,则可以考虑,让i-1,i-2,i-3的任何一个不为U(加法计数)

dp[1]=1,dp[2]=2,dp[3]=4,dp[4]=7;
 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int f[40];
 4 int main(){
 5     f[1] = 1, f[2] = 2, f[3] = 4;
 6     for (int i = 4; i <= 32;i++){
 7         f[i] = f[i - 1] + f[i - 2] + f[i - 3];
 8     }
 9     int n;
10     while(cin>>n&&n){
11         int ans = (1 << n);
12         ans -= f[n + 1];
13         cout << ans << endl;
14     }
15 }

 

个人觉得第一种的思路比较好想(容易想错),第二种的更简洁

 

好无聊,不想写了

 

真的猛士,敢于开数学!!!!!

标签:pac   bit   from   i++   计数   长度   组合数   安全   use   

原文地址:https://www.cnblogs.com/guaguastandup/p/10606653.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!