[数位dp] bzoj 2431: [HAOI2009]逆序对数列

本文介绍了一道名为“逆序对数列”的题目,并通过数位DP的方法来解决该问题。该题曾在HAOI2009中出现,通过使用前缀和优化递推过程,有效地计算了在特定约束条件下的逆序对数量。

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

bzoj 2431: [HAOI2009]逆序对数列 http://www.lydsy.com/JudgeOnline/problem.php?id=2431

让我身心俱疲的一题
非常讨厌龙dalao的”很简单啊“”我几个for搞完了“”不就是前缀和吗“
蒟蒻瑟瑟发抖

数位dp
把模版反过来问

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
int f[1100][1100];//前i个数的逆序对数j个的符合数列数量 
int main()
{
    //i比前面的数都大 所以放在最后面对逆序对数的贡献位0 放在i-1的位置贡献为1 放在0的位置就是i-1 所以贡献为0~i-1 
    //f[i][j]=sigma(f[i-1][j-k]); 1<=k<=i-1; (k即为i放的位置)
    //利用前缀和优化
    int n,k;
    scanf("%d%d",&n,&k);
    for (int i=0;i<=n;i++) f[i][0]=1;
    for (int i=1;i<=n;i++)
    {
        int sum=f[i-1][0];
        for (int j=1;j<=k;j++)
        {
            if (j>=i) sum-=f[i-1][j-i]; // 因为用了前缀和 因为i的最多的贡献为i-1 当前的贡献是j 所以就是j-(i-1)=j-i+1 前缀和s[i]-s[j-1] 所以now=now-f[i-1][j-i]
            sum+=f[i-1][j];
            f[i][j]+=sum;
            while (f[i][j]<10000) f[i][j]+=10000;
            f[i][j]%=10000;
        }
    }
    printf("%d\n",f[n][k]);
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值