對於所有的數據,有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