Luogu P4933 大师dpBy cellur925

Posted nopartyfoucaodong

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Luogu P4933 大师dpBy cellur925相关的知识,希望对你有一定的参考价值。

题目传送门

题目大意:给你一个序列,求子序列为等差数列的子序列个数。序列长度$n<=2000$,最高的塔高$v<=20000$。


这种计数类的题,大概就是dp的套路了⑧。开始设计的是一个错误的状态:设$f[i][j]$为到前$i$个塔选了$j$个的方案数,但是我们再看一看就会发现这是错的,因为等差数列啊,我们并没有考虑公差鸭。所以我们再设计一个状态:设$f[i][j]$表示到第$i$个塔为止,公差为$j$的方案数。开始想的是$O(n^3)$算法 ,还要枚举公差,但是后来发现不需要特意枚举公差,只要枚举一个数的之前的数,直接用他们的公差即可。复杂度$O(n^2)$。

因为公差可能有负数,所以我们再加上一个大数即可。

开始不加快读竟然会T一个点,加了就A了??? 我佛了233.

Code

#include<cstdio>
#include<algorithm>
#define maxn 1090

using namespace std;
typedef long long ll;
const ll moder=998244353;

int n,fake=20000;
int h[maxn];
ll ans,f[maxn][40009];

void re(int &x)
{
    x=0;
    char ch=getchar();
    bool flag=false;
    while(ch<0||ch>9) flag|=(ch==-),ch=getchar();
    while(ch>=0&&ch<=9) x=(x<<3)+(x<<1)+(ch^48),ch=getchar();
    x=flag ? -x : x;
}

int main()
{
    re(n);
    for(int i=1;i<=n;i++) re(h[i]);
    for(int i=1;i<=n;i++)
        for(int j=1;j<i;j++)
        {
            (f[i][h[i]-h[j]+fake]+=f[j][h[i]-h[j]+fake]+1)%=moder;
            (ans+=f[j][h[i]-h[j]+fake]+1)%=moder;
        }
    (ans+=n)%=moder;
    printf("%lld
",ans); 
    return 0;
}

 

以上是关于Luogu P4933 大师dpBy cellur925的主要内容,如果未能解决你的问题,请参考以下文章

luogu P1095守望者的逃离dpBy cellur925

Luogu P1736 创意吃鱼法dpBy cellur925

Luogu P2051[AHOI2009]中国象棋dpBy cellur925

Luogu P3694 邦邦的大合唱站队 状压dpBy cellur925

CF767C Garland 树形dpBy cellur925

CF580D Kefa and Dishes 状压dpBy cellur925