• 51nod1009


    给定一个十进制正整数N,写下从1开始,到N的所有正数,计算出其中出现所有1的个数。
     
    例如:n = 12,包含了5个1。1,10,12共包含3个1,11包含2个1,总共5个1。
    Input
    输入N(1 <= N <= 10^9)
    Output
    输出包含1的个数
    Input示例
    12
    Output示例
    5
    思路:一看到这道题就想到了记忆化搜索,奈何太久没打过了,忘记了太多要素,因此被此题卡了四个多小时。。。。。吐血啊
    #include<stdio.h>
    #include<string.h>
    int dis[12];
    int lg,len;
    int s[12];
    int dp[12][2];
    int check(int a){
    	int i=0;
    	if(a<0)
    	return 0;
    	int ans=0;
    	for(i=0;i<=a;i++)
    	ans+=dis[i]*s[i];
    	//printf("%d %d
    ",a,ans);
    	return ans;
    }
    int dfs(int pos,int lg){
    	if(pos<0)
    	return 0;
    	int num=lg?dis[pos]:9;
    //	printf("num=%d
    ",num);
    	if(!lg&&dp[pos][lg]!=-1)
    	return dp[pos][lg];
    	
    	int i,j;
    	int ans=0;
    	
    	for(i=0;i<=num;i++){//计算当第pos位为i时时,后面pos-1位有多少种情况; (当为i时,计算的范围为i*10^(pos)----(i+1)*10^(pos)-1) 
    		if(i==1){
    			if(lg&&i==num)
    			{ans=ans+check(pos-1)+1+dfs(pos-1,lg&&(i==num));//0---check(pos-1),所以要加一 
    				
    				//printf("a%d %d %d
    ",pos,i,ans);
    			}
    			else
    			{
    				ans=ans+s[pos]+dfs(pos-1,lg&&(i==num));//当此位为1时,它没有被限制,那么可以分解成10000+(0---9999)(假设当前有五位) 
    				//printf("b%d
    ",ans);//0---9999的每一个数都可以在前面加一个 。 
    			}
    		}
    		else
    		{ans+=dfs(pos-1,lg&&(i==num));
    	//	printf("c%d
    ",ans);
    		}
    	}
    //	printf("%d %d
    ",pos,ans);
    	if(!lg)
    	dp[pos][lg]=ans;
    	return ans;
    }
    int main(){
    	int n;
    	len=0;
    	scanf("%d",&n);
    	int i;
    	s[0]=1;
    	for(i=1;i<=9;i++)
    	s[i]=s[i-1]*10;
    	while(n){
    		dis[len++]=n%10;
    		n=n/10;
    	}
    	memset(dp,-1,sizeof(dp));
    	printf("%d
    ",dfs(len-1,1));
    	return 0;
    }
    

      

  • 相关阅读:
    css设置页面内容不能被选中
    bootstrap栅格系统
    MVC框架
    类模板
    c++编译器模板机制剖析
    函数模板与函数重载
    函数模板当参数强化
    泛型编程—函数模板
    用友GRP-u8 注入-RCE漏洞复现
    漏洞代码调试(二):Strtus2-001代码分析调试
  • 原文地址:https://www.cnblogs.com/cglongge/p/9309482.html
Copyright © 2020-2023  润新知