51nod 1020 逆序排列
2017-12-05 20:49
253 查看
1020 逆序排列
离线处理,二维dp[i][j]表示前i个有k个逆序对的数量。f(n,k)=f(n,k−1)+f(n−1,k)−f(n−1,k−n)
用滚动数组储存
#include <algorithm> #include <cstring> #include <cstdio> using namespace std; #define INF 0x3fffffff typedef long long ll; const int P=1e9+7; const int N=20005; int ans ,dp[3] ; struct node { int n,k; int id; }b ; bool cmp(node n1,node n2) { if (n1.n==n2.n) return n1.k < n2.k; else return n1.n < n2.n; } int n,mk; int main() { register int i,j,k,t; scanf("%d",&t); n=0;mk=0; for (i=1;i<=t;i++) { scanf("%d%d",&b[i].n,&b[i].k); b[i].id=i; n=max(n,b[i].n); mk=max(mk,b[i].k); } memset(ans,0,sizeof(ans)); sort(b+1,b+t+1,cmp); int st,prs,pre=0,now=1,p=1;dp[0][0]=1; for (i=2;i<=n;i++) { k=min(i*(i-1)/2,mk); for (j=0;j<=k;j++) { st=max(0,j-i+1); prs=st==0?0:dp[pre][st-1]; dp[now][j]=(dp[pre][j]-prs+P)%P; if (j>=1)dp[now][j]=(dp[now][j]+dp[now][j-1])%P; } while (p<=t) { if (b[p].n!=i) break; ans[b[p].id]=dp[now][b[p].k]; p++; } now^=1;pre^=1; } for (i=1;i<=t;i++) printf("%d\n",ans[i]); return 0; }
相关文章推荐
- 51Nod 1020 逆序排列 【思维+dp】求和差推公式
- 51NOD 1020 逆序排列
- 51nod 1020 逆序排列 (DP_好题)
- 51nod 1020 逆序排列
- [反序表 DP] 51Nod 1020 逆序排列
- 51Nod 1020 逆序排列
- 51nod 1020逆序排列
- 51nod 1020 逆序排列——dp
- 51nod 1020 逆序排列
- 51nod 1020 逆序排列
- 51nod 1020 逆序排列(dp)
- 51nod-1020 逆序排列
- 51nod 1020:逆序排列 DP
- 51Nod 1020 逆序排列
- 【dp】51nod - 1020 逆序排列
- 51nod 1020 逆序排列【Dp+思维递推优化】好题!好题!好题!
- 51nod 1020 逆序排列 | dp
- 【反序表+DP】51Nod 1020 逆序排列
- 51nod 1020 逆序排列【DP】
- 51nod 1020 逆序排列(dp+离线)