1. 程式人生 > >bzoj 2660: [Beijing wc2012]最多的方案【dp】

bzoj 2660: [Beijing wc2012]最多的方案【dp】

否則 cst main 字典 註意 clu ios include 如果

有點神奇的dp
首先註意到任意一個數都能被表示成若幹個斐波那契數的和的形式
先求出n可以字典序最大的表示
設f[i][0/1]表示第i個斐波那契數選或者不選
如果當前數不選,那就選比他小的兩個數,否則,需要不選比他小的兩個數(連續的影響)

#include<iostream>
#include<cstdio>
using namespace std;
const int N=105;
long long n,a[N],s[N],top,f[N][2];
int main()
{
    scanf("%lld",&n);
    a[0]=1,a[1]=1;
    for(int i=2;i<=90;i++)
        a[i]=a[i-2]+a[i-1];
    for(int i=90;i>=1;i--)
        if(n>=a[i])
            n-=a[i],s[++top]=i;
    f[top][0]=(s[top]-1)/2,f[top][1]=1;
    for(int i=top-1;i>=1;i--)
    {
        f[i][1]=f[i+1][0]+f[i+1][1];
        f[i][0]=((s[i]-s[i+1]-1)/2)*f[i+1][1]+((s[i]-s[i+1])/2)*f[i+1][0];
    }
    printf("%lld\n",f[1][0]+f[1][1]);
    return 0;
}

bzoj 2660: [Beijing wc2012]最多的方案【dp】