照看小猫
在一个风和日丽的午后,少佐给薇尔莉特伊芙嘉登安排了一个任务。
任务大致是这样的,接下来的一周,薇尔莉特需要照顾 N 只小猫咪。为了方便管理这N 只猫咪,
薇尔莉特准备给每只猫咪取一个独一无二的名字。取名字要征求猫咪本咪的同意才可以。
但这些猫咪都非常有个性,绝不接受很长的名字。
现给出每只猫咪所能容忍名字的长度上限。
请你为所有猫咪取名字,请问共有多少种不同的方案。
名字仅包含小写英文字母。结果可能非常大,所以请将结果对 77797 取模
如果无方案,请输出 -1
解题思路:
这个题我开始真的非常纠结。。。菜是原罪
突然想到如果我们将要命名的猫咪按照名字的长度上限进行递增排序,那每次在后面猫咪进行计算时只需要减去前一只猫的一种就可以了!!
详情请看题解~
AC代码
#include <cstdio>
#include <algorithm>
using namespace std;
int p[15]= {
1};//让数组第一个元素等于1,那么从第二个元素(也就是a[1]开始方案数*26)
int a[10005];
int main() {
int n;
scanf("%d",&n);//记录猫咪数量
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);//记录每只猫咪的最长容忍名字长度上限
sort(a+1,a+1+n);
for(int i=1; i<=10; i++) {
p[i]=p[i-1]*26%77797;
}
for(int i=2; i<=10; i++)
p[i]=(p[i-1]+p[i])%77797;
//这是最重要的一点!!对于10个字以内的名字方案进行记录
long long int ans=1;
for(int i=1; i<=n; i++) {
ans=(p[a[i]]-(i-1))*ans%77797;//第二只猫咪开始,减去上一只猫咪用掉的一个方案(叠加)
}
if(ans<=0) {
printf("-1");//如果答案小于等于0,要输出-1;
return 0;
}
printf("%lld",ans);//输出答案
}
附:初来乍到,如果有不足之处,恳请各位大牛指正,如果题解有错误或者没写清楚的地方也欢迎在评论区提问~