Dynamic Programming training within 20

https://www.luogu.org/problem/P1370

Title effect: Σ (1 <= l <= r <= n) F (l, r), where F (l, r) represents [l, r] of the different nature of the sequences between the number of

analysis:

If this question is N ^ 2 ^ data, then I would do, but the requirement is O (n) calculated

The same section title count , fixed endpoints L , then consider dp

设dp[i]表示F[i,i]+F[i,i+1]+F[i,i+2]+....+F[i,n]

If there are no duplicate numbers, then

dp[i]=(dp[i+1]<<1)+2

meaning is:

dp[i+1]= F[i+1,i+1]+F[i+1,i+2]+F[i+1,i+3]+....+F[i+1,n]

dp[i]= F[i,i]+ F[i,i+1]+ F[i,i+2]+ F[i,i+3] +....+ F[i,n]

I believe one can understand the

But there are duplicate how to do?

If ai == aj (i <j)

则dp[i]-=dp[j+1]+1;

The reason is behind all F [j + 1, j + 1] ..... are repeated once (contact ai, then aj)

That is 1 F [j, j] selected j j j selected or not selected in the program

code (the code too lazy to hit):

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 998244353
#ifdef ONLINE_JUDGE
char *TT,*mo,but[(1<<15)+2];
#define getchar() ((TT==mo&&(mo=(TT=but)+fread(but,1,1<<15,stdin)),TT==mo)?0:*TT++)
#endif
inline int read(){
    int x=0,c=0,f=1;
    for(;c<'0'||c>'9';c=getchar())f=c!='-';
    for(;c>='0'&&c<='9';c=getchar())x=x*10+c-'0';
    return f?x:-x;
}
int head[100010];
int a[100010],b[100010];
ll dp[100010];
ll ans;
int n;
int main(){
    n=read();
    for(int i=1;i<=n;i++){
        a[i]=read();
        b[i]=a[i];
    } 
    sort(b+1,b+n+1);
    int cnt=unique(b+1,b+n+1)-b-1;
    for(int i=1;i<=n;i++)a[i]=lower_bound(b+1,b+cnt+1,a[i])-b;
    dp[n]=2;
    head[a[n]]=n;
    for(int i=n-1;i>0;i--){
        dp[i]=(dp[i+1]*2+2)%mod;
        if(head[a[i]]){
            dp[i]=(dp[i]-dp[head[a[i]]+1]+mod-1)%mod;
            head[a[i]]=i;
        }
        head[a[i]]=i;
    }
    for(int i=1;i<=n;i++){
        ans=(ans+dp[i])%mod;
    }
    cout<<ans;
    return 0;
}

Guess you like

Origin www.cnblogs.com/wzxbeliever/p/11808252.html