【郑轻邀请赛 H】 维克兹的进制转换

【题目链接】:https://acm.zzuli.edu.cn/zzuliacm/problem.php?id=2134

【题意】

【题解】

设f[i]表示数字i分解为二进制数的方案数;

如果i为偶数->则i的最后一位是0
f[i]=f[i/2]+f[i/2-1]
->考虑在最后加1个0或者加1个2
这里i/2-1,减去1实际上是在新加的2借位,因为0变成2之后,整体会+2;则前面需要减去2作为补充;
如果i为奇数
f[i]=f[i/2];
因为i的二进制最后一位为1;
则如果你把它变成0或变成2都会使它变成偶数;
所以只有老老实实地加上1了;
这里的/2操作实际上就是二进制右移一位;把原本的最后一位去掉;
其对应的方案数最后再加上0、1、2;
对应了状态的转移。

【Number Of WA

1

【完整代码】

#include <bits/stdc++.h>
using namespace std;
#define rep1(i,x,y) for (int i = x;i <= y;i++)
#define LL long long

const int N = 1e7+100;

int n;
int f[N];

int main()
{
    //freopen("D:\\rush.txt","r",stdin);
    ios::sync_with_stdio(0);
    f[0] = 1;f[1]=1;f[2] = 2;
    rep1(i,3,10000000)
        if (i&1)
        {
            f[i]=f[i>>1];
        }
        else//i%2==0
        {
            f[i]=f[i>>1]+f[(i>>1)-1];
        }
    int T;
    cin >> T;
    while (T--)
    {
        int x;
        cin >> x;
        cout << f[x]<<endl;
    }
    return 0;
}
posted @ 2017-10-04 18:44  AWCXV  阅读(134)  评论(0编辑  收藏  举报