poj1850和poj1496(组合数)

题目意思:给出一串字符串问按照文中的序号排,序号是多少。

思路:先计算出n位字符,一共有多少种情况,再减去比这个字符大的情况种数。

主要步骤一:

长度为一的字符串有26种(a,b,c,...,z)   C(26,1)

长度为二的字符串有:

    以a开头的25种(ab,ac,ad,...,az)  C(25,1)

    以b开头的24种(bc,bd,...,bz)      C(24,1)

    ...                                                 ...

    以y开头的有1种,yz       C(1,1)

一共 C(25,1)+C(24,1)+...+C(1,1)=1+2+3+..+25=25*26/2=C(26,2)

其实这里有一个重要的组合数公式:

长度为三的自然有C(26,3)种

那只要一个循环就可以将每一位一共的情况计算出来。

主要步骤二:

减去每一位比它大的字符串。这里可以想象成拿小球了。

例如: abc     

计算第一位  abc     比a大的字符有25个,只要从中选三个字符组合就比它大  所以是C(25,3)

计算第二位 abc      比b大的字符有24个,只要从中选两个构成(axx)就比它大,所以是C(24,2)

计算第二位 abc      比c大的字符有23个,只要从中选一个构成(abx)就比它大,所以是C(23,1)

这样就计算出来序号了。但是   注意不可法的情况输出0

下面是poj1850的代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int c[30][30];

void init()//组合数打表 
{
    c[0][0]=1;
    for(int i=1;i<30;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=i;j++)
            c[i][j]=c[i-1][j]+c[i-1][j-1];
    }
}

int main()
{
    string s;
    init();
    cin>>s;
    int len=s.length();
    int res=0;
    for(int i=1;i<len;i++)//不合法情况 
    {
        if(s[i-1]>=s[i])
        {
            cout<<res<<endl;
            return 0;
        }
    }
    for(int i=1;i<=len;i++)//加每一位情况 
        res+=c[26][i];
    for(int i=0;i<len;i++)//减大于字符串的情况 
        res-=c[26-(s[i]-'a'+1)][len-i];
    cout<<res<<endl;
    return 0;
}
View Code

poj1496:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
int c[30][30];

void init()
{
    c[0][0]=1;
    for(int i=1;i<30;i++)
    {
        c[i][0]=1;
        for(int j=1;j<=i;j++)
            c[i][j]=c[i-1][j]+c[i-1][j-1];
    }
}

int main()
{
    string s;
    init();
    while(cin>>s)
    {
        int len=s.length();
        int res=0,flag=0;
        for(int i=1;i<len;i++)
        {
            if(s[i-1]>=s[i])
            {
                cout<<res<<endl;
                flag=1;
            }
        }
        if(flag)
            continue;
        for(int i=1;i<=len;i++)
            res+=c[26][i];
        for(int i=0;i<len;i++)
            res-=c[26-(s[i]-'a'+1)][len-i];
        cout<<res<<endl;
    }
    return 0;
}
View Code

猜你喜欢

转载自www.cnblogs.com/xiongtao/p/10895890.html