zoukankan      html  css  js  c++  java
  • bzoj2660最多的方案

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2660

    当然可以看出  选了第 i 个斐波那契数<=>选了第 i - 1 和第 i - 2 个斐波那契数;

    还有一个关键是:题目给出的这个数能表示成几个斐波那契数的和<=>该数可以被用斐波那契数分解。

    如果把选不选每一个斐波那契数用二进制表示的话,首先要尽量使最高位最大,才能算出最多的方案。

    把第一次分解的那些斐波那契数的位置记录下来,用dp表示这些数选不选。

      若选这个数,则上一个选了或者没选而分解到更小的都行;

      若不选这个数,则它的方案数画一画就知道是  它与上一个分解出的数中间的0的个数 * 选上一个数 + (……0的个数+1)*不选上一个数;

    我觉得自己应该好好利用斐波那契数的这个写在第一行的性质。本题怎么可能不与这有关呢?

      自己考虑到“上一个数也可以不选而……”的时候就不行了,这是没有考虑到利用自己假设已经算出来的值(即“不选这个数的方案数”);还是经验不足吧。

    蜜汁:注释掉的部分有什么不对?

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    using namespace std;
    const int N=1e6+5;
    ll n,c[N],cnt,dp[90][2],pos[N],xnt;
    int main()
    {
        scanf("%lld",&n);
        c[1]=1;c[0]=1;
        for(int i=2;c[i-1]<=n;i++)c[i]=c[i-1]+c[i-2],cnt=i-1;
        for(int i=cnt;i&&n;i--)if(c[i]<=n)n-=c[i],pos[++xnt]=i;
    //    dp[xnt][1]=1;dp[xnt][0]=(pos[xnt]-1)/2;/////
    //    for(int i=xnt-1;i;i--)
    //    {
    //        dp[i][1]=dp[i+1][0]+dp[i+1][1];
    //        dp[i][0]=dp[i+1][0]*(pos[i]-pos[i+1])/2+dp[i+1][1]*(pos[i]-pos[i+1]-1)/2;
    //    }
    //    printf("%lld",dp[1][0]+dp[1][1]);
        sort(pos+1,pos+xnt+1);
        dp[1][1]=1;dp[1][0]=(pos[1]-1)/2;
        for(int i=2;i<=xnt;i++)
        {
            dp[i][1]=dp[i-1][1]+dp[i-1][0];
            dp[i][0]=(pos[i]-pos[i-1])/2*dp[i-1][0]+(pos[i]-pos[i-1]-1)/2*dp[i-1][1];
        }
        printf("%lld",dp[xnt][0]+dp[xnt][1]);
        return 0;
    }
  • 相关阅读:
    通过mixins方法处理调取服务器时间
    记录个人对vuex的简单理解
    利用弹性布局实现垂直居中
    vue.set的适用方法
    深拷贝和浅拷贝的实现方法
    Maven安装步骤
    build tools
    Git
    Url和Uri的区别
    函数式编程语言
  • 原文地址:https://www.cnblogs.com/Narh/p/9133941.html
Copyright © 2011-2022 走看看