标签:
题解:
dp[i][j]表示前i个数的排列有j个逆序列的对数,根据逆序列的性质,最大的放在前i个数列中,新增加0~i-1的序列
dp[i][j]=sum(dp[i-1][j-k]) (0<=k<i)
代码:
o(n^3)算法。直接裸就行了
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define INF 2097152 typedef pair<int,int> P; const double eps=1e-9; const int maxn=1050; const int mod=1e9+7; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int dp[maxn][maxn]; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) dp[i][0]=1; for(int i=1;i<=n;i++) { for(int j=1;j<=k;j++) { for(int p=0;p<=i-1;p++) { if(j>=p) dp[i][j]+=dp[i-1][j-p]; dp[i][j]=(dp[i][j]+10000)%10000; } } } printf("%d\n",dp[n][k]); return 0; }
o(n^2)算法。用一个前缀和来加速
#include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define fs first #define ll long long #define CLR(x) memset(x,0,sizeof x) #define MC(x,y) memcpy(x,y,sizeof(x)) #define SZ(x) ((int)(x).size()) #define FOR(it,c) for(__typeof((c).begin()) it=(c).begin();it!=(c).end();it++) #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define INF 2097152 typedef pair<int,int> P; const double eps=1e-9; const int maxn=1050; const int mod=1e9+7; ll read() { ll x=0,f=1;char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();} return x*f; } //----------------------------------------------------------------------------- int dp[maxn][maxn]; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) dp[i][0]=1; for(int i=2;i<=n;i++) { int t=dp[i-1][0];//t求的是前i-1个数的i段长也就是(0~n-1)的连续长度 for(int j=1;j<=k;j++) { if(j-i>=0) t-=dp[i-1][j-i]; t+=dp[i-1][j]; dp[i][j]=(t+10000)%10000; } } printf("%d\n",dp[n][k]); return 0; }
标签:
原文地址:http://www.cnblogs.com/byene/p/5760979.html