【Luogu】P3205合唱队(区间DP)
通过这题我发现我已经不会DP了
区间DP,f[i][j]是从左面转移来的,d[i][j]是从右面转移来的
然后DP方程是
if(q[i]<q[i+1]) f[i][j]+=f[i+1][j]; if(q[i]<q[j]) f[i][j]+=d[i+1][j]; f[i][j]%=mod; if(q[i]<q[j]) d[i][j]+=f[i][j-1]; if(q[j]>q[j-1]) d[i][j]+=d[i][j-1]; d[i][j]%=mod;
然后就是代码啦
#include<cstdio> #include<algorithm> #include<cstring> #include<cctype> #include<cstdlib> #define maxn 1020 #define mod 19650827 using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int rai[maxn],dow[maxn]; int q[maxn]; int f[maxn][maxn]; int d[maxn][maxn]; int main(){ int n=read(); for(int i=1;i<=n;++i) q[i]=read(); for(int i=1;i<=n;++i) f[i][i]=1; for(int len=2;len<=n;++len){ for(int i=1;i+len-1<=n;++i){ int j=i+len-1; if(q[i]<q[i+1]) f[i][j]+=f[i+1][j]; if(q[i]<q[j]) f[i][j]+=d[i+1][j]; f[i][j]%=mod; if(q[i]<q[j]) d[i][j]+=f[i][j-1]; if(q[j]>q[j-1]) d[i][j]+=d[i][j-1]; d[i][j]%=mod; } } printf("%d",(f[1][n]+d[1][n])%mod); return 0; }