dotcpp1117-- K-进制数 递推

                                                      K-进制数

考虑包含N位数字的K-进制数. 定义一个数有效, 如果其K-进制表示不包含两连续的0. 

例: 
1010230 是有效的7位数 
1000198 无效 
0001235 不是7位数, 而是4位数. 

给定两个数N和K, 要求计算包含N位数字的有效K-进制数的总数. 

假设2 <= K <= 10; 2 <= N; 4 <= N+K <= 18.

输入

两个十进制整数N和K

输出

十进制表示的结果

样例输入
2
10
样例输出
90

 

拿到这个题看了一眼范围,暴力应该会被T,但是我还是试了一发,结果被T的一发不可收拾!可是不暴力的话应该怎么做呢?

其实这是一个递推的问题:

我们先看N=1的情况,显然有 k-1 种情况符合条件,只有一种条件不符合情况,因为第一位为0 是不对的,我们记 AC1=k-1,WA1=1;

当N=2的时候,需要和N=1的情况相联系,第二位的选项还是k-1种,满足条件的情况分为两部分,一部分是第一位满足情况 k-1种,以及第一位不满足的情况,所以AC2=(k-1)*(AC1+WA1);不满足条件的情况就发生了改变,即在AC1 前面补0的情况,当然00必定不符合情况,以后也无法凑成满足条件的,所以我们不需要考虑,即 WA2=AC1

当N=3时,还是需要看N=2的情况,第三位的选项有 k-1种,因为第三位不会取到0,而也不会有00的情况,所以第三位仍然可以与AC2和WA2想匹配,即AC3=(k-1)*(AC2+WA2);不满足的情况仍然是在AC2的前面补0,即 WA3=AC2

所以递推式就出来喽,AC=(k-1)*(preAC+WA); WA=preAC;我们求得最终的AC就可以AC了

代码很简单 :

#include<cstdio>
#include<string>
#include<cmath>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stack>
#include<queue>
#define ll long long
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
inline int _read() {
    char ch = getchar();
    int sum = 0;
    while (!(ch >= '0' && ch <= '9'))ch = getchar();
    while (ch >= '0' && ch <= '9')sum = sum * 10 + ch - 48, ch = getchar();
    return sum;
}
const int inf=0x3f3f3f3f;
const int mm=0;

int main()
{
	int n,k;
	cin>>n>>k;
	int ac=k-1,wa=1;
	for(int i=2;i<=n;i++){
		int pre=ac;
		ac=(k-1)*(ac+wa);// 前面补非零*(上一个可以的+前面为0的) 
		wa=pre;//前补零的  
	} 
	cout<<ac<<endl;
	
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值