洛谷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;
}
原文地址:https://www.cnblogs.com/pjxpjx/p/12543081.html