poj1850~Code~(组合数的应用)

 

今天的数论测试的题目。我只写出了这一题大哭

对数学中的组合数的求法记得更深了:

void get()             //组合数的求法
{
	int i,j;
	for( i=0;i<=26;i++)
	for( j=0;j<=i;j++)
	{
		if(j==0||i==j)
			c[i][j]=1;
		else c[i][j]=c[i-1][j]+c[i-1][j-1];
	}
}

这里用到组合数的一个很关键的思想就是: 如果有n身高不同的人,要选m个人从高到低站成一排,有多少种排法?

其实就是C[n][m]个,因为从n个人里选出m个后,他们的站位就已经确定了。

so,对这题,我就讲下求的过程吧,拿s=bdg这个字符串做例子。首先,s的长度len=3

已经是3位的,因为所谓的code是从a增到z再增到ab再增到yz再增到bdg的,即先从1位增到2位再增到3位的。

那么a增到z,code量是26个字母里面选1个,ab增到yz,code量是26个字母里选两个。

然后要计算yz到bdg的过程中有多少code量。

bdg的前面是经过a_ _的。那么a开头的3位有多少个呢?就是25个字母里选2个。因为空格里的字母不能小于等于a。,所以不会包含a。

然后看第2位,是一个d,d和b之间有个c,那么还需要计算c_有多少个,是23个里面选1个

然后看g,g和d之间有e和f。故就是1+1.

所以答案等于C[26][1]+C[26][2]+C[25][2] +C[23][1]+1+1

#include<iostream>
#include<string>
#include<cmath>
using namespace std;
int n,c[27][27],a[12];
void get()             //组合数的求法
{
	int i,j;
	for( i=0;i<=26;i++)
	for( j=0;j<=i;j++)
	{
		if(j==0||i==j)
			c[i][j]=1;
		else c[i][j]=c[i-1][j]+c[i-1][j-1];
	}
}
int main()
{
	int i,j,ans;
	char s[12];
	get();
	cin>>s+1;
	int len=strlen(s+1);
	for(i=2;i<=len;i++)
	if(s[i]<=s[i-1])
	{
		cout<<"0"<<endl;
	   return 0;
	}
	ans=0;
	for(i=1;i<=len-1;i++)  //假如有3位,先把1位和2位的总数加起来
	ans+=c[26][i];
	s[0]='a'-1;
	for(i=1;i<=len;i++)
	{         //每次计算他前面的,如果是bf,b只计算a,f只计算cde
            //c[25-j][len-i]
		for(j=s[i-1]-'a'+1;j<s[i]-'a';j++)    
		{
			ans+=c[25-j][len-i];
		}
	}
	cout<<ans+1<<endl;
}


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值