P1866 编号

题目传送门

一、题意解析

每只兔子的喜好整数范围不一样,有的大,有的小。想求方案的总数量,就是所有的可行方案解数。

所有方案解,就是所有可能,不能丢失某种情况。

那么,如何才能不丢失情况呢?就是最全的,也可以理解为最多的。

咋能最多呢?如果让兔子们随便挑选,肯定完蛋了~,所以,需要让他们有“秩序”的选择,而这个秩序,就是我们解题的关键。

什么秩序呢?就是猜一个你认为对的顺序,然后再证明它的正确性。

其实,贪心这玩意,无外乎先猜由小到大,再猜最大到小,再猜a+b,不行,再猜a-b,balabalabala...

先猜一下按号码由小到大,那就是范围小的先来,范围大的后来。以[8,3,5,6]为例,就是先让范围为3的先来,有3种,5的后来,因为前面占了一种,所以是4种,...
s=3(51)(62)(83)=240种。

下面来简单证明一下这种方法的正确性。
极限思维法,假设a,b是两只兔子的喜好整数。那么
sum1=a(b1)
sum2=b(a1)

讨论一下sum1sum2的大小关系:
sum1sum2=abaab+b=ba
也就是说,如果ba>0sum1>sum2,换句人话来说就是b>a可以使得结果更大,即a,b按从小到大排序即可。

两个是这样的情况,那么多个呢?多个可以视为多组两个,每两个都由小到大,自然就是一个排序的意思了~

二、关键点

1、贪心策略的选择和证明

2、同余定理
(a+b+c)%k=((a+b)%k+c)%k
(abc)%k=((ab)%kc)%k

三、完整代码

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int MOD = 1000000007;
const int N = 51;   //50只兔子是上限值
int n;              //具体是几只兔子
int num[N];         //字牌编号

int main() {
    LL ans = 1;
    cin >> n;
    for (int i = 1; i <= n; i++)cin >> num[i];
    sort(num + 1, num + 1 + n);//排序,贪心

    for (int i = 1; i <= n; i++) {
        ans *= (num[i] - i + 1);
        ans %= MOD;  //边乘边模,使用了同余定理
    }
    //输出结果
    cout << ans << endl;
    return 0;
}
posted @   糖豆爸爸  阅读(55)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2017-08-23 学习OpenResty编程
Live2D
点击右上角即可分享
微信分享提示