有点坑的一道组合题。
解题思路:
首先对于每一个字符串,长度比其小的一定比其小,这一块的总贡献是 ∑ i − 1 l e n − 1 C 26 i \sum_{i-1}^{len-1}C_{26}^i ∑i−1len−1C26i。
然后是长度相等的,当确定前 i i i 位相等,当前位(也就是 i + 1 i+1 i+1 位,这里与程序实现有所不同)的字符为 j j j (转26进制,同样与程序实现不同)时,产生的方案贡献为 C 26 − j − 1 l e n − i − 1 C_{26-j-1}^{len-i-1} C26−j−1len−i−1,这里需要枚举累加。
代码:
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string a;
int ans;
int C(int m,int n){
if(m==0)return 1;
int ans=1;
for(int i=n-m+1;i<=n;i++)
ans*=i;
for(int i=1;i<=m;i++)
ans/=i;
return ans;
}
int main(){
cin>>a;
for(int i=0;i<a.length();i++)
if(a[i]<=a[i-1]){
printf("0\n");
return 0;
}
for(int i=1;i<a.length();i++)
ans+=C(i,26);
for(int i=0;i<a.length();i++){
for(int j=(i==0?1:a[i-1]-'a'+2);j<a[i]-'a'+1;j++)
ans+=C(a.length()-i-1,26-j);
}
printf("%d",ans+1);
return 0;
}
反思:
本身不是一道非常难的组合题,但是还是做了好长时间,中途还 WA 了一发,这一块要多练练。