二进制的难题 51Nod

一个十进制整数被叫做权势二进制,当他的十进制表示的时候只由0或1组成。例如0,1,101,110011都是权势二进制而2,12,900不是。

当给定一个n的时候,计算一下最少要多少个权势二进制相加才能得到n。


Input单组测试数据。 
第一行给出一个整数n (1<=n<=1,000,000)Output输出答案占一行。Sample Input

9

Sample Output

9

解题思路:先将范围内的所以权势二进制储存,在进行0/1背包;

代码:
#include <iostream>

using namespace std;

const int MAX = 1000009;
int a[1000];
int dp[MAX];
int ai;

void DP(int x)
{
    if(x>1000000)
        return;
    a[ai++] = x;
    DP(x*10+1);
    DP(x*10);
    return;
}

int main()
{
    a[0] = 0;
    ai = 1;
    DP(1);
    int x;
    cin>>x;
    for(int i =0;i<MAX;i++)
        dp[i] = MAX;
    dp[0] = 0;

   

    for(int i =1;i<ai;i++)
    {
        if(a[i]<=x)
        {
            for(int j = a[i];j<=x;j++ )
                if(dp[j-a[i]]<MAX)
                dp[j] = min(dp[j],dp[j-a[i]]+1);
        }
    }

    cout<<dp[x]<<endl;

    return 0;
}

解法2:给出n,问至少可以表示为多少个数位上面只有0和1的数字之和。
显然答案即为n的十进制数位的最大值,即max(n%10,n%100,n%1000....)
时间复杂度O(logn)。

代码:

# include <bits/stdc++.h>
using namespace std;

char s[10];

int main ()
{
    int ans=0;
    scanf("%s",s);
    for (int i=0; s[i]; ++i) ans=max(ans,s[i]-'0');
    printf("%d
",ans);
    return 0;
}

原文地址:https://www.cnblogs.com/a2985812043/p/7478109.html