HDU多校10 - 6880 Permutation Counting(dp+思维)
生活随笔
收集整理的這篇文章主要介紹了
HDU多校10 - 6880 Permutation Counting(dp+思维)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目鏈接:點擊查看
題目大意:給出一個長度為 n - 1 的 01 序列 b 用來表示排列?a 的相對大小關系,b[ i ] = 0 說明 a[ i ] < a[ i + 1 ] ,b[ i ] = 1 說明 a[ i ] > a[ i + 1 ],問 a 共有多少種合法方案
題目分析:考慮動態規劃,dp[ i ][ j ] 代表第 i 個數作為前 i 個數中的第 j 大的方案數,這樣轉移方程就比較簡單了:
這樣時間復雜度是 O( n^3 ) 的,可以用前綴和優化一下,優化為 O( n^2 )
代碼:
#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=5e3+100;const int mod=1e9+7;LL a[N],dp[N][N],sum[N];int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--){memset(dp,0,sizeof(dp));int n;scanf("%d",&n);for(int i=2;i<=n;i++)scanf("%lld",a+i);dp[1][1]=1;for(int i=2;i<=n;i++){for(int j=1;j<=n;j++)if(j<=i)sum[j]=(sum[j-1]+dp[i-1][j])%mod;elsesum[j]=sum[j-1];for(int j=1;j<=i;j++){if(a[i]==1)//j+1~ndp[i][j]=(sum[n]-sum[j-1]+mod)%mod;else//1~j-1dp[i][j]=sum[j-1];}}LL ans=0;for(int i=1;i<=n;i++)ans=(ans+dp[n][i])%mod;printf("%lld\n",ans);}return 0; }?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的HDU多校10 - 6880 Permutation Counting(dp+思维)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SPOJ - OPTM Optimal
- 下一篇: 中石油训练赛 - Equidistant