http://codeforces.com/problemset/problem/1307/E
题意:
n个草一列,m头牛,每头牛有喜欢的草和需要吃这种草的数量。吃饱后会变成路障。
现在选择一些牛,分别从左往右吃和从右往左吃。如果一头牛遇到了路障或者走到尽头还是没有吃够它就会不高兴。
想要选择尽可能多的牛使得他们都高兴,问你最大数量和方案数。
解析:
- 显然一边不会出现两个相同草的牛。
- 假设枚举左边第一个牛停下的位置,那么左边每个格子假设会有牛停在这里,那么这个牛已经确定了。
- 对于不同的牛,方案树之间相乘。
- 一种牛,先要考虑能不能左右各放一个。假设有x种数量(吃这种草指定数量的牛)可以放两边,y种数量只能放一边。
- 如果x=0,那么只能放一边,方案数为y
- 如果x=1且y=0,那么也只能放一边,方案数为2
- 否则一边x中选一个,另外一边有x-1+y可以选,方案数为x(x-1+y)
代码:
/*
* Author : Jk_Chen
* Date : 2020-03-05-16.39.33
*/
#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define rep(i,a,b) for(int i=(int)(a);i<=(int)(b);i++)
#define per(i,a,b) for(int i=(int)(a);i>=(int)(b);i--)
#define mmm(a,b) memset(a,b,sizeof(a))
#define pb push_back
#define pill pair<int, int>
#define fi first
#define se second
#define debug(x) cerr<<#x<<" = "<<x<<'\n'
const LL mod=1e9+7;
const int maxn=5e3+9;
const int inf=0x3f3f3f3f;
LL rd(){ LL ans=0; char last=' ',ch=getchar();
while(!(ch>='0' && ch<='9'))last=ch,ch=getchar();
while(ch>='0' && ch<='9')ans=ans*10+ch-'0',ch=getchar();
if(last=='-')ans=-ans; return ans;
}
#define rd rd()
/*_________________________________________________________begin*/
int a[maxn];
int ct[maxn],now[maxn];
bool vis[maxn][maxn];
int main(){
int n=rd,m=rd;
rep(i,1,n){
a[i]=rd;
ct[a[i]]++;
}
rep(i,1,m){
vis[rd][rd]=1;
}
LL ans=0,mx=0;
rep(i,0,n){
now[a[i]]++;
if(i==0||vis[a[i]][now[a[i]]]){
LL nowans=1,sum=1;
if(i==0)sum=0;
rep(j,1,n){
if(j==a[i]){
LL x=0;
for(int k=1;k<=ct[j]-now[j];k++){
if(vis[j][k]&&k!=now[j]){
x++;
}
}
if(x){
nowans=nowans*x%mod;
sum++;
}
}
else{
LL x=0,y=0;
for(int k=1;k<=min(now[j],ct[j]-now[j]);k++){
if(vis[j][k]){
x++;
}
}
for(int k=min(now[j],ct[j]-now[j])+1;k<=max(now[j],ct[j]-now[j]);k++){
if(vis[j][k]){
y++;
}
}
if(x==0&&y==0){continue;}
if(x==0){
nowans=nowans*y%mod;
sum++;
}
else if(x==1&&y==0){
sum++;
nowans=nowans*2%mod;
}
else{
sum+=2;
nowans=nowans*(x*(x-1+y))%mod;
}
}
}
if(sum>mx){
mx=sum;ans=nowans;
}
else if(sum==mx){
ans=(ans+nowans)%mod;
}
}
}
printf("%lld %lld\n",mx,ans);
return 0;
}
/*_________________________________________________________end*/