zoukankan      html  css  js  c++  java
  • 递推3--位数问题

    递推3--位数问题

    一、心得

    问题想清楚

    注意边界

    二、题目及分析

    三、代码及结果

    方法一:排列组合

      1 /*
      2 位数问题 :
      3 在所有的n位数中,有多少个数中有偶数个数字3?
      4 
      5 方法一:
      6 排列组合
      7 n位数中有x个三的情况为:c(n,x)*9^(n-x) 
      8 还要减去首位为0的情况:c(n-1,x)*9^(n-1-x) 
      9 故为: c(n,x)*9^(n-x)- c(n-1,x)*9^(n-1-x) 
     10 calc[n][x]= c(n,x)*9^(n-x)
     11 dp[n][x]= c(n,x)*9^(n-x)- c(n-1,x)*9^(n-1-x)
     12 dp[n][x]: n位数中有x个三的情况数目 
     13  
     14 
     15 方法二:
     16 递推
     17  
     18  
     19 */ 
     20 
     21 /*
     22 算法优化后面再看,先把基础功能实现 
     23 */
     24 #include <iostream>
     25 #define Max 10 
     26 using namespace std;
     27 int dp[Max];//n位数中有x个三的情况数目
     28  
     29 
     30 //求c(n,x)
     31 int  combination(int n,int x){
     32     /*
     33     c(5,3)=(5*4*3)/(3*2*1) 
     34     */
     35     int ans=1;
     36     if(n<x) return 0;
     37     else if(n==x) return 1;
     38     else{
     39         for(int i=n,j=1;j<=x;j++,i--){
     40             ans=ans*i/j;//这样一定能除尽 
     41         }
     42     }
     43     return ans;
     44 }
     45 
     46 //计算c(n,x)*9^(n-x)  
     47 int calcTimes(int n,int x){
     48     int ans=combination(n,x);
     49     for(int i=1;i<=n-x;i++){
     50         ans*=9;
     51     }
     52     return ans;
     53 } 
     54 
     55 //dp操作,没做初始化,因为全局变量都是0, 
     56 void dpOperation(int n){
     57     for(int i=0;i<=n;i++){
     58         if(n==1){//一位数的话,第一位可以是0 
     59             dp[i]=calcTimes(n,i);
     60         }
     61         else if(n>1){
     62             dp[i]=calcTimes(n,i)-calcTimes(n-1,i);
     63         }    
     64     }
     65     
     66 //    for(int i=1;i<=n;i++){//计算1-n位数的情况 
     67 //        for(int j=0;j<=i;j++){//计算i位数有j个3的情况 
     68 //            
     69 //        } 
     70 //    }
     71 } 
     72 
     73 //打印dp数组
     74 void print(int n){
     75     for(int i=0;i<=n;i++){
     76         cout<<n<<"位数中有"<<i<<"个3的数目:"<<dp[i]<<" "<<endl;
     77     }
     78     cout<<endl;
     79 } 
     80 
     81 //计算偶数个3
     82 int even3(int n){
     83     int ans=0;
     84     for(int i=0;i<=n;i++){
     85         if(i%2==0){
     86             ans+=dp[i];
     87         }
     88     }
     89     return ans;
     90 } 
     91 
     92 
     93 int main(){
     94     int n=6;
     95     //int ans=combination(10,7);
     96     //int ans=calcTimes(2,2);
     97     //cout<<ans<<endl;
     98     dpOperation(n);//dp操作,没做初始化,因为全局变量都是0,
     99     //cout<<calcTimes(n,0)<<" "<<calcTimes(n-1,0)<<endl;
    100     print(n);//打印dp数组
    101     int ans=even3(n);//计算偶数个3
    102     cout<<n<<"位数中有偶数个3的数目:"<<ans<<endl; 
    103     return 0;
    104 }

    方法二、递推

     1 /*
     2 位数问题 :
     3 在所有的n位数中,有多少个数中有偶数个数字3?
     4 
     5 方法一:
     6 排列组合
     7 n位数中有x个三的情况为:c(n,x)*9^(n-x) 
     8 还要减去首位为0的情况:c(n-1,x)*9^(n-1-x) 
     9 故为: c(n,x)*9^(n-x)- c(n-1,x)*9^(n-1-x) 
    10 calc[n][x]= c(n,x)*9^(n-x)
    11 dp[n][x]= c(n,x)*9^(n-x)- c(n-1,x)*9^(n-1-x)
    12 dp[n][x]: n位数中有x个三的情况数目 
    13  
    14 
    15 方法二:
    16 递推
    17 这种题目一般都是从i-1位推导第i位,就是看第n位取不取3 
    18 
    19 f[i][0]表示前i位取偶数个3有几种情况
    20 f[i][1]表示前i位取奇数个3有几种情况 
    21 则状态转移方程为:
    22 f[i][0]=f[i-1][0]*9+f[i-1][1] 
    23 f[i][1]=f[i-1][1]*9+f[i-1][0] 
    24 边界条件:f[1][1]=1 f[1][0]=9
    25 其实可以看做是取完最后一位取第一位,而0不能做第一位,所以到n的时候,是*8 
    26  
    27  
    28 */ 
    29 
    30 /*
    31 算法优化后面再看,先把基础功能实现 
    32 */
    33 #include <iostream>
    34 using namespace std;
    35 int main(){
    36     int n;
    37     int f[1005][2]={0};
    38     cin>>n;
    39     f[1][1]=1; 
    40     f[1][0]=9;
    41     for(int i=2;i<=n;i++){
    42         int x=f[1][0];
    43         if(i==n) x--;//其实可以看做是取完最后一位取第一位,而0不能做第一位,所以到n的时候,是*8 
    44         f[i][0]=(f[i-1][0]*x+f[i-1][1])%12345; 
    45         f[i][1]=(f[i-1][1]*x+f[i-1][0])%12345; 
    46     } 
    47     cout<<f[n][0]<<endl;
    48     return 0;
    49 } 

  • 相关阅读:
    【LOJ#10027】魔板
    【LOJ#2653】山峰和山谷
    【POJ2449】第k短路
    【HAOI2008】移动玩具
    【洛谷P1379】八数码难题
    【NOIP2002】字串变换
    【CH2501】矩阵距离
    【CH2601】电路维修
    【NOIP2009】靶形数独
    树的子结构
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/7002863.html
Copyright © 2011-2022 走看看