找规律DP 七十和十七

本文探讨了一种通过递推公式解决特定排列问题的方法。针对一个初始无序的序列,通过对序列进行逐步调整以达到完全有序状态的过程进行了详细分析,并给出了解决方案的具体递推公式。文中还提供了一个C++实现的示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题面去内网找~~
这个一看真的不知道是个啥。
观察可知,如果想要处理第i位上的元素使之有序,必须要把前i-1位全部变成有序。我们再分开来想,
如果第i位是i,多移动0步,
第i位是1,多移动1步。
第i位是2,多移动2步:把2提前,再把1提前。
第i位是3,多移动4步:把3提前,重复之前两步。
…….
也就是说,最后一位是i,移动2^(i-1)步。
因此,把前i为变成有序,要走(i-1某种情况的步数)+2^(最后一位是啥)。我们合起来考虑,对于前i-1位同一种情况,最后一位多移动的值加和是(2^i-1),而前i-1位共有!(i-1)种情况,所以f[i]=f[i-1]i+(2^i-1) !(i-1)。递推就好了。
说实在,考试时真的没想到,就交上去了一个dfs,可能因为T2耗的时间太长了,心里有点发慌,没有真的静下心去想。考试心态有待提高。

#include<cstdio>
#define ll long long
ll n,i=3,s=1,A=2,p=4,d=1000000007,m=d-2;
int main()
{
    scanf("%lld",&n);
    for(;i<=n;i++)
         s=s*i%d+(p-1)*A%d,A=A*i%d,p=p*2%d;
    while(m)
    {
        if(m&1)s=s*A%d;
        A=A*A%d;
        m/=2;
    }
    printf("%lld",s);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值