洛谷P3795 钟氏映射【DP】【黄】

博客详细解析了洛谷P3795题目的解题思路,主要涉及动态规划的概念。通过设立状态方程f[i]表示有i个数时满足条件的映射数,分析两种情况:映射到自身和形成交叉映射,并给出状态转移方程。最后,博主提到由于内存限制,使用滚动数组进行优化。

Date:2022.02.13
题目描述
设集合N=M={x∣∈N+,x<=k,k∈N+}N=M=\{x|\in N_+,x<=k,k\in N_+\}N=M={xN+,x<=k,kN+}
设f为N到M的映射。
求满足:
f[f(x)]=x的不同的映射ff的个数,由于答案较大,输出答案对14233333取余的数即可。
输入格式
输入一个正整数k
输出格式
输出满足f[f(x)]=x的不同的映射ff的个数对14233333取余得到的数。
输入输出样例
输入 #1复制
3
输出 #1复制
4
说明/提示
四个映射分别为:
f(1) f(2) f(3)
1 2 3
1 3 2
2 1 3
3 2 1
数据范围:
对于20%的数据,1<=k<=91<=k<=91<=k<=9
对于其它的80%的数据,1<=k<=1071<=k<=10^71<=k<=107
内存20MB…(一开始开1MB把自己坑了)

题意解释:N、M集合中分别有kkk个数,之间可两两配对(每个元素不可重复配对在>=2对中)或自己配对(或者理解为不配对,反正占用1种情况)。
思路:设状态方程为:f[i]f[i]f[i]:集合N、M中有iii个数时符合条件的映射数。
f[f[x]]==xf[f[x]]==xf[f[x]]==x即表示映射的关系,因此只能有两种分类:
f[x]==x−>f[f[x]]==xf[x]==x -> f[f[x]]==xf[x]==x>f[f[x]]==x,即xxx的映射即为自己(或者说xxx无映射),这显然是1种情况。对答案贡献为f[i−1]∗1f[i-1]*1f[i1]1
f[x]==y&&f[y]==xf[x]==y \&\& f[y]==xf[x]==y&&f[y]==x,这体现为N、M的映射关系(可看为一个X形状的交叉)。对答案贡献为f[i−2]∗(i−1)f[i-2]*(i-1)f[i2](i1)【即第iii个与(1,i−1)(1,i-1)(1,i1)中任一个配对,因此(i−1)(i-1)(i1)种配对情况;至于为什么是f[i−2]f[i-2]f[i2]?个人认为更好理解的是:我们关心的无非是在前面(1,i−1)(1,i-1)(1,i1)中选中的是否在之前已配对?如果未配对,直接配对,那么这样(1,i−1)(1,i-1)(1,i1)中就转化为i−2i-2i2个元素的配对问题,顺序显然影响不了什么,因此完全可等价为f[i−2]f[i-2]f[i2](尽管不一定是前i−2i-2i2个,但完全可以等价);如果已配对,相当于拆散了这个配对,使被选择的和iii配对,原来与被选择的元素配对的元素当然可以再找其它配对呀,剩下的理由同上,仍可以等价为f[i−2]f[i-2]f[i2]】。
因此状态转移方程:f[i]=f[i−1]+f[i−2]∗(i−1);f[i]=f[i-1]+f[i-2]*(i-1);f[i]=f[i1]+f[i2](i1);
初始状态:f[0]==1f[0]==1f[0]==1;(相当于无法配对或给自己配对,看怎么理解了) f[1]=2;f[1]=2;f[1]=2;(不配对或X形状配对)。【这里为了方便滚动数组取模,iii都减了1,对应的实际意义应为f[i+1]f[i+1]f[i+1]】。
除此之外,空间太小了,显然开不下1e7,滚动数组优化下(不然喜提re

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 1010,mod=14233333;
typedef long long LL;
LL n,m,p,k,f[3];
int main()
{
    cin>>k;f[0]=1;f[1]=2;LL res=2;
    for(int i=3;i<=k;i++)
    {
        f[res]=(f[(res-1+3)%3]+f[(res-2+3)%3]*(i-1)+mod)%mod;
        res++;res%=3;
    }
    cout<<f[(k-1+3)%3];
    return 0;
}
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值