洛谷P1569 Generic Cow Protests

2020.3.21

P1569 Generic Cow Protests

简单题意:

给定 \(n(n≤1000)\)个数,要求分成几组(必须连续),使得每一组之和,求最多能分成多少段。
如果无解输出"Impossible"

思路:

前缀和思想,令 \(sum[i]\)表示第 \(1\)个数到第 \(i\)个数之和,\(f[i]\)表示前 \(i\)个数最多分组
如果前 \(i\)个数之和 \(≥0\),那么前 \(i\)个肯定至少有一组了,\(f[i]=1\)
如果 \(j<i\)并且 \(j到i\)之和 \(≥0\),前 \(j\)个数至少可分一组,则 \(j到i\)可以成为一组了
转移方程便是:

\(f[i]=max(f[i],f[j]+1)\),其中\(j<=i\)且\(f[j]!=0\)

code:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
using namespace std;
const int N=1005; 
int a[N],sum[N],n,f[N]; 
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
        sum[i]=sum[i-1]+a[i];
        if(sum[i]>=0)//如果前缀和大于0,至少有一组
        f[i]=1; 
    }
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<i;j++)//j到i-1即可,因为j<i
        {
            if(f[j]&&sum[i]-sum[j]>=0)
            {
                f[i]=max(f[j]+1,f[i]);
            }
        }
    }
    if(f[n]>0)//如果可以分组
    cout<<f[n];
    else//否则
    cout<<"Impossible";//输出"Impossible",不看题的教训 
    return 0;
}
上一篇:JAVA开发-泛型实例


下一篇:记一次Linux 4.15.0-65-generic安装Elasticsearch成功的过程