SOJ 2785_Binary Partitions

1791 단어 ACM_동적 기획
[제의 뜻] 한 수를 2진수로 표시하고 모두 몇 가지 표시 방법이 있는지 구한다.
【분석】 사고방식 1: 완전 가방
【코드】
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <cmath>
#include<ctime>
using namespace std;
const int INF=0x3fffffff,maxn=1e5+40;
const int mod=1000000;
const int total=2000050;
int f[total];
int main (void)
{
    int T,temp;
    f[0]=1;
    scanf("%d",&T);
    for(int i=0;i<=20;i++)//2^20<total<2^21
        for(int j=(1<<i);j<total;j++)
             f[j]+=f[j-(1<<i)]%mod;
   while(T--)
   {
       scanf("%d",&temp);
       printf("%d
",f[temp]%mod);    } }

코드는 zoj에서 AC를 하는데 soj에서 계속 TLE를 해요. 오랫동안 고쳐서 겨우 AC를...슬그머니 울다
사고방식2: 다른 사람의 블로그를 보면 점차적인 사상을 사용할 수 있다. 이진수의 측면에서 어떤 수든 그의 앞의 수+1으로 표시할 수 있다. 그러나 이 수n이 짝수라면 그는 그의 절반 n/2로 표시할 수 있다. 곧 n/2가 한 자리를 왼쪽으로 옮길 것이다.
【코드】
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <cmath>
#include<ctime>
using namespace std;
const int INF=0x3fffffff,maxn=1e5+40;
const int mod=1000000;
const int total=2000050;
int f[total];
int main (void)
{
    int T,num;
    f[0]=1;
    for(int i=0;i<total;i++)
    {
        if(i%2==0)
            f[i]=(f[i/2]+f[i-1])%mod;
        else
            f[i]=f[i-1]%mod;
    }
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&num);
        printf("%d
",f[num]); } }

좋은 웹페이지 즐겨찾기