Codeforces 1307 E Cow and Treats —— 想法

This way

题意:

现在有一行,每格都有草,每个草的甜度为ai,现在有m头牛,每头牛喜欢的甜度和要吃的格数都告诉你,现在你要安排这些牛去吃草,每头牛只能从左到右或从右到左吃,它吃饱了之后就会停下来,并且之后的牛不能再通过这个格子,并且吃过的草不会再长出来。问你最多有多少牛可以吃饱并且在此前提下有多少种方法。

题解:

这种问你情况的题目并不要求让你输出具体怎么做,有时候我就会从怎么将它做出来考虑,那样就不容易做出来,其实这道题目很简单。因为奶牛吃完了之后就不允许其它奶牛通过,所以一个方向吃相同草的奶牛最多只有一个,然后另外一个方向有可能也有一个。这样我们就分每种草考虑左边以及右边的个数。
我们枚举从左往右最远的牛的位置,然后再枚举草的种类,这时候有一些情况:如果当前草的种类和最远的草的种类相同的话,说明这种情况左边只有一种,也就是我们枚举到的最远的牛(自己理解一下),右边的情况如果右边的草的数量>=左边的草的数量就-1因为这头牛被安排了,然后还有一些情况。。

#include
using namespace std;
#define ll long long
const int N=5e3+5;
const ll mod=1e9+7;
int a[N];
vector<int>vec[N];
int l[N],r[N];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
    int x,y;
    for(int i=1;i<=m;i++)
        scanf("%d%d",&x,&y),vec[x].push_back(y);
    for(int i=1;i<=n;i++)
        sort(vec[i].begin(),vec[i].end());
    ll a1=0,a2=0;
    for(int i=0;i<=n;i++){
        memset(l,0,sizeof(l));
        memset(r,0,sizeof(r));
        for(int j=1;j<=i;j++)
            l[a[j]]++;
        for(int j=i+1;j<=n;j++)
            r[a[j]]++;
        int f=i?0:1,mx=i?1:0;//f表示这次有没有正好会在第i次结束的奶牛
        ll s=1;
        //cout<<vec[a[i]].size()<<endl;
        for(auto j:vec[a[i]]){
            if(j==l[a[i]]){
                f=1;
                break;
            }
        }
        if(!f)continue;
        for(int j=1;j<=n;j++){
            int lef=0,rig=0;
            for(auto x:vec[j]){
                if(x>l[j])
                    break;
                lef++;
            }
            for(auto x:vec[j]){
                if(x>r[j])
                    break;
                rig++;
            }
            if(j==a[i])
                lef=0,rig-=r[j]>=l[j];
            if(!lef&&!rig)
                continue;
            if(lef>rig)
                swap(lef,rig);
            if(!lef)
                s=s*rig%mod,mx++;
            else if(rig==1)
                s=s*2%mod,mx++;
            else
                s=s*lef*(rig-1)%mod,mx+=2;
        }
        if(mx>a1)
            a1=mx,a2=s;
        else if(mx==a1)
            a2=(a2+s)%mod;
    }
    printf("%lld %lld\n",a1,a2);
    return 0;
}
/*
5 2
1 1 1 1 1
1 2
1 3


*/

你可能感兴趣的:(想法)