fzu 1533

眉间皱痕 提交于 2020-08-07 04:04:52

Problem 1533 Subset

Accept: 299    Submit: 740
Time Limit: 1000 mSec    Memory Limit : 32768 KB

Problem Description

整数集合Sn={1,2,...,n}的非空子集如果不含两个相邻的自然数,则称为好子集。你的任务是求好子集的个数。

Input

有多组测试数据。每个测试数据一行,有一个正整数,表示n(1≤n≤70)。

Output

对于每组测试数据,输出一个数表示Sn的好子集的个数

Sample Input

3

Sample Output

4

Hint

{1},{2},{3},{1,3}.

Source

FOJ月赛-2007年9月



开头用dp, 从后往前推理

dp(i) 为以第i项作为结尾的好子集个数

第i项可以选,也可以不选。

选的情况下因为不相邻的限制,就递归dp(i-2)。  不选递归dp(i-1)

dp(i)=dp(i-2)+dp(i-1)

最终结果要减一,因为算出来的包含空集

后面知道这是fibonacci ,就直接计算了。

#include <cstdio>
#include <cmath>
#include <string.h>
#include <iostream>
using namespace std;

const int maxn=70+5;

typedef long long LL;
LL d[maxn];

LL dp(int n)//包含空集情况
{
if(n==1)// {}, {1}
{
return 2;
}
else if(n==2)// {}, {1}, {2}
{
return 3;
}

LL &ans = d[n];
if(ans>0)
return ans;
// 每层都可以选或不选
ans = dp(n-1) + dp(n-2);
return ans;
}

long long fib[maxn]={1, 2, 3};

void fibonacci(int n)
{
for(int i=3;i<=n;i++)
{
fib[i] = fib[i-1] + fib[i-2];
//        cout<<fib[i]<<endl;
}
}


int main()
{
int n;
fibonacci(70);
while(scanf("%d", &n)==1)
{

//        printf("%lld", dp(n)-1);//减去一个空集 fzu坑,不能用lld 要用 I64d
//        cout << dp(n)-1 << endl;
cout << fib[n]-1 << endl;
}

return 0;
}

关于fibonacci参考链接:
http://courseware.eduwest.com/courseware/0350/content/zhonghe/tc11.html

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!