-
H - The Battle of Chibi
- HDU - 5542
- 题意:给出长度为n的序列,问这个序列中有多少个长度为m的单调递增子序列。
- 思路:dp[i][j],长度为 j 的单调递增子序列第 j 个位置 为 a [ i ]的方案数 ,可以由在其前面 并且
- 小于它 的 长度为 j-1 的 单调递增子序列的方案数求和 得到,长度为 j-1 的状态可以用树状数组维护。
-
#include<bits/stdc++.h> using namespace std; const int mod=1e9+7; #define maxn 1004 int dp[maxn][maxn],tree[maxn][maxn],ans; int t,n,m,a[maxn],ls[maxn],id; int lowbit(int x) { return x&(-x); } void updata(int pos,int x,int ad) { while(x<=n+2) { tree[pos][x]=(tree[pos][x]+ad)%mod; x+=lowbit(x); } } int getsum(int pos,int x) { int sum=0; while(x) { sum=(sum+tree[pos][x])%mod; x-=lowbit(x); } return sum; } int main() { scanf("%d",&t); for(int qq=1; qq<=t; qq++) { memset(tree,0,sizeof(tree)); id=ans=0; scanf("%d%d",&n,&m); for(int i=1; i<=n; i++) { scanf("%d",&a[i]); ls[i]=a[i]; dp[1][i]=1; } sort(ls+1,ls+n+1); int sum[1005]; for(int i=1; i<=n; i++) sum[i]=lower_bound(ls+1,ls+n+1,a[i])-ls; printf("Case #%d: ",qq); for(int i=2; i<=m; i++) for(int j=1; j<=n; j++) { int hk=sum[j]; updata(i-1,hk,dp[i-1][j]); dp[i][j]=getsum(i-1,hk-1)%mod; dp[i][j]%=mod; } for(int i=1; i<=n; i++) ans=(ans+dp[m][i])%mod; printf("%d\n",ans); } return 0; }
H - The Battle of Chibi HDU - 5542 -dp-树状数组
最新推荐文章于 2022-02-04 17:01:48 发布