對於所有的數據,有1<=N<=1000,所有的數字都是不大於109的正整數。
第一問:可以發現對一座山有影響的只可能是比它高的山,所以我們可以將山按高度從大到小排序,依次插入每座山。對於高度相同的山一起處理,按關鍵值從小到大排序,然後將每座山能插入的位置數乘到答案中,即min(i,a[i].key+1)+num-1,num為它在高度相同的山中的排名。
第二問:為了不重復計算,我們每次將高度相同的山拿出來,然後讓插入之後的順序也不改變。這樣就可以DP計算,f[i][j]=f[i-1][0]+f[i-1][1]+……+f[i-1][j],其實f數組還可以降到一維。注意每次計算時要將f數組清零。
#include #include #include #include #include #include #define F(i,j,n) for(int i=j;i<=n;i++) #define D(i,j,n) for(int i=j;i>=n;i--) #define ll long long #define maxn 1005 #define mod 2011 using namespace std; int n,ans1=1,ans2=1,f[maxn]; struct data{int h,k;}a[maxn]; inline int read() { int 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; } inline bool cmp(data x,data y) { return x.h==y.h?x.ky.h; } int main() { int i,j; n=read(); F(i,1,n) a[i].h=read(),a[i].k=read()-1; sort(a+1,a+n+1,cmp); for(int i=1;i<=n;i=j) { memset(f,0,sizeof(f)); f[0]=1; for(j=i;j<=n&&a[i].h==a[j].h;j++) { ans1=ans1*(min(i,a[j].k+1)+j-i)%mod; for(int k=1;k