CCF 有趣的数

题意:给你4个数0,1,2,3,用这四个数字组成n位的数,其中 0必须 在1前面,  2必须在三前面,问你n位数没有前导0的有多少个。

解题思路:

1) 状态压缩DP,dp[i][j] 表示 到了第i位  出来了那几个数,分别的状态为多少。 j(1-15),然后求出各自的DP系数就行了。

解题代码:

  1 // File Name: 有趣的数.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年03月30日 星期一 16时46分03秒
  4
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #define LL long long
 25 #define M 1000000007
 26 using namespace std;
 27 LL dp[2000][17];
 28 int a[10];
 29 int b[10];
 30 int solve(int tmp , int t[])
 31 {
 32   int tt =0 ;
 33   while(tmp)
 34   {
 35     tt ++ ;
 36     t[tt] = tmp % 2;
 37     tmp /= 2;
 38   }
 39 }
 40 int ok(int x , int y)
 41 {
 42    memset(a,0,sizeof(a));
 43    memset(b,0,sizeof(b));
 44    solve(x,a);
 45    solve(y,b);
 46    if(x == y )
 47    {
 48       int tt1 = a[1] + a[2];
 49       int tt2 = a[3] + a[4];
 50       int k = 0 ;
 51       if(tt1)
 52           k ++ ;
 53       if(tt2 )
 54           k ++ ;
 55       return k ;
 56    }
 57    int tx = 0 ;
 58    int ty = 0 ;
 59    for(int i = 1;i <= 4;i ++)
 60        tx += a[i];
 61    for(int i = 1;i <= 4;i ++)
 62        ty += b[i];
 63    int c = 0 ;
 64    for(int i = 1;i <= 4;i ++)
 65        if(a[i] != b[i])
 66            c ++;
 67    if(tx - ty  == 1 && c == 1 )
 68    {
 69        if(b[1] == 0 && a[1] == 1)
 70        {
 71            if(b[2] == 1)
 72                return 0 ;
 73        }
 74        if(b[3]== 0 &&  a[3] == 1){
 75            if(b[4] == 1)
 76                return 0 ;
 77        }
 78        return 1;
 79    }else{
 80      return 0 ;
 81    }
 82 }
 83 int main(){
 84    int n ;
 85    scanf("%d",&n);
 86    dp[1][1] = 0 ;
 87    dp[1][2] = 1 ;
 88    dp[1][4] = 1;
 89    dp[1][8] = 1;
 90    for(int i = 2  ;i <= n;i ++)
 91    {
 92       for(int j= 1;j <= 15 ;j ++)
 93       {
 94          for(int s = 1; s <= 15;s ++)
 95          {
 96             if(ok(j,s) != 0 )
 97             {
 98               dp[i][j] = (dp[i][j]+ok(j,s)*dp[i-1][s])%M;
 99             }
100          }
101         // printf("%lld ",dp[i][j]);
102       }
103      // printf("\n");
104    }
105
106    printf("%d\n",dp[n][15]%M);
107 return 0;
108 }

2) 组合数学。

具体参见:http://erona.me/2014/12/05/CCF%E6%A8%A1%E6%8B%9F%E9%A2%98-%E6%9C%89%E8%B6%A3%E7%9A%84%E6%95%B0/

时间: 2025-01-04 10:50:54

CCF 有趣的数的相关文章

CCF模拟题 有趣的数

有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一

CCF系列之有趣的数(201312-4)

题目链接: http://115.28.138.223:81/view.page?opid=4 试题名称: 有趣的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请

CCF 201312-4 有趣的数 (数位DP, 状压DP, 组合数学+暴力枚举, 推公式, 矩阵快速幂)

问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000). 输

CCF模拟题4-有趣的数

问题描述 我们把一个数称为有趣的,当且仅当:1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次.2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前.3. 最高位数字不为0.因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301.请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000).  输出格式

有趣的数

有趣的数 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 100

有趣的数(动态规划)

问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数. 输入格式 输入只有一行,包括恰好一个正整数n (4 ≤ n ≤ 1000). 输

P2022 有趣的数

P2022 有趣的数 题目描述 让我们来考虑1到N的正整数集合.让我们把集合中的元素按照字典序排列,例如当N=11时,其顺序应该为:1,10,11,2,3,4,5,6,7,8,9. 定义K在N个数中的位置为Q(N,K),例如Q(11,2)=4.现在给出整数K和M,要求找到最小的N,使得Q(N,K)=M. 输入输出格式 输入格式: 输入文件只有一行,是两个整数K和M. 输出格式: 输出文件只有一行,是最小的N,如果不存在这样的N就输出0. 输入输出样例 输入样例#1: Sample 1: 2 4

ccf201312-4有趣的数,递推

http://115.28.138.223/view.page?gpid=T2 问题描述 我们把一个数称为有趣的,当且仅当: 1. 它的数字只包含0, 1, 2, 3,且这四个数字都出现过至少一次. 2. 所有的0都出现在所有的1之前,而所有的2都出现在所有的3之前. 3. 最高位数字不为0. 因此,符合我们定义的最小的有趣的数是2013.除此以外,4位的有趣的数还有两个:2031和2301. 请计算恰好有n位的有趣的数的个数.由于答案可能非常大,只需要输出答案除以1000000007的余数.

普转提——有趣的数,欢乐ABC,打游戏

有趣的数——构造符合条件的数 给你一个区间,问有多少个数符合每一位中,只有一个数字和其他数字不同,也就是其他数字都相同,有且只有一个异类: 数据范围是1e16: 因为只考虑数量而不用管大小: 只要0到9枚举出来就好了: #include<cstdio> #include<map> #include<cstring> #include<algorithm> using namespace std; typedef long long ll; map<ll