首页 > 技术文章 > codevs2034 01串2

yanlifneg 2016-04-25 16:43 原文

/*
一开始认为是个水题 直接模拟 
没想到只得了50分 一看数据吓niao了
模拟妥妥的TLE
实在不好优化了0.0(最快O(m)) 
然后借鉴别人的 DP+神奇的输出
DP:状态:f[i][j] 前i个字符出现j次1的数字个数
很容易想到 如果i是1  f[i][j]=f[i][j]+f[i-1][j-1] 
如果i是0  f[i][j]=f[i][j]+f[i-1][j] 
初始化 i==0||j==0时 个数为1
然后就是神奇的输出了0.0
 看代码吧 
*/


/*
TLE 50 
模拟 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
int n,l,m,num;
int main()
{
    cin>>n>>l>>m;
    int s=(2<<n-1)-1;
    for(int i=0;i<=s;i++)
      {
          int li=0,x=i,y;
          while(x>0)
            {
                y=x%2;
                x=x/2;
                if(y==1)li++;
          }
        if(li<=l)num++;
        if(num==m)
          {
              int a[33]={0},li=0;
              while(i>0)
                {
                    a[++li]=i%2;
                    i=i/2;
              }
            for(int j=n;j>=1;j--)
              cout<<a[j];
            return 0;
          }
      }
}
/*
AC  100
DP 
*/
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
using namespace std;
ll f[33][33],n,l,m;
int main()
{
    ll i,j;
    cin>>n>>l>>m;
    for(i=0;i<=n;i++)f[i][0]=1;
    for(i=0;i<=l;i++)f[0][i]=1;
    for(i=1;i<=n;i++)
      for(j=1;j<=l;j++)
        f[i][j]=f[i-1][j]+f[i-1][j-1];
    m--;//减掉0的一种情况 
    for(i=n;i>=1;i--)//枚举位置  
      if(m&&f[i-1][l]<=m)//输出1的条件:前i-1位中含‘剩余’l的数字个数不超过m并且m>=1 
        {
          cout<<1;
          m=m-f[i-1][l];//与‘目标’还差几 
          l--;//‘剩余’l的数字个数
        }
      else cout<<0;
    return 0;
}

 

推荐阅读