URAL 1009 URAL 1012 URAL 1013

探讨了如何计算不包含连续两个零的合法K进制数的总数,使用动态规划解决该问题,并提供了两种实现方式:一种适用于较小的N值,另一种采用高精度算法处理更大的N。

题目链接:

http://acm.timus.ru/problem.aspx?space=1&num=1009

题目翻译:

我们定义一个合法的K进制数为一个不含连续两个零的K进制数。

例如:
1010230 是一个合法的7位数。
1000198 不是合法的数。
0001234 不是7位数,是一个合法的4位数。

给你N,和K,求出N位的K进制数的总数。

2 <= K <= 10; N >= 2; 4 <= N+K <= 18。

输入:两个十进制数N和K 

输出:  用十进制表示的总数 

注意三个题不同的是N的范围,所以后两道需要用高精度

题解:dp[i]=dp[i-1]*(k-1)+dp[i-2]*(k-1);

1009代码:

#include <iostream>
#include <stdio.h>
using namespace std;
int dp[19];
int main()
{
	int n,k;
	while(scanf("%d%d",&n,&k)!=EOF)
	{
		k--;
		dp[0]=1,dp[1]=k;
    	for(int i=2;i<=n;i++)
		    dp[i]=k*(dp[i-1]+dp[i-2]);
		printf("%d\n",dp[n]);
	}
	return 0;
}
1012和1013代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int MAXLEN = 1900;
class BigInt
{
public:
	int data[MAXLEN];
	BigInt(const int n = 0)
	{
		memset(data, 0, sizeof(data));
		data[0] = 1;
		data[1] = n;
	}
	BigInt operator = (const int n)
	{
		return *this = BigInt(n);
	}
	BigInt operator = (const BigInt &ob)
	{
		memcpy(data, ob.data, sizeof(data));
		return *this;
	}
	BigInt operator + (const BigInt &ot)
	{
		BigInt sum;
		int i;
		sum.data[0] = data[0]>ot.data[0] ? data[0] : ot.data[0];
		for (i = 1; i <= sum.data[0]; ++ i)
		{
			sum.data[i] += data[i] + ot.data[i];
			sum.data[i+1] += sum.data[i] / 10;
			sum.data[i] %= 10;
		}
		while (sum.data[i] != 0)
		{
			sum.data[i+1] += sum.data[i] / 10;
			sum.data[i] %= 10;
			i += 1;
		}
		sum.data[0] = i - 1;
		sum.data[0] = i-1;
		while(sum.data[sum.data[0]] == 0 && sum.data[0] > 1)
			sum.data[0] -= 1;
		return sum;
	}
	BigInt operator * (const int n)
	{
		BigInt product;
		int i;
		for (i = 1; i <= data[0]; ++ i)
		{
			product.data[i] += data[i] * n;
			product.data[i+1] += product.data[i] / 10;
			product.data[i] %= 10;
		}
		while (product.data[i] != 0)
		{
			product.data[i+1] += product.data[i] / 10;
			product.data[i] %= 10;
			i += 1;
		}
		product.data[0] = i-1;
		while(product.data[product.data[0]] == 0 && product.data[0] > 1)
			product.data[0] -= 1;
		return product;
	}
	friend ostream& operator << (ostream &os, BigInt &ob)
	{
		for (int i = ob.data[0]; i >= 1; -- i)
			os << ob.data[i];
		return os;
	}
};
BigInt a,b,c,t;
int main()
{
	int n,k;
	scanf("%d%d",&n,&k);
	k--;
	a=1,b=k;
	for(int i=2;i<=n;i++)
	{
		t=a;
		a=b;
		b=(t+a)*k;
	}
	cout<<b<<endl;
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值