题意:给定n个序列,判断一下存不存在一个子序列的和大于总的序列和,但子序列长度不能是n
思路:一开始看懂题这不就是dp求最小子段和吗?心想这么水,迅速码好最大子段和一提交,果断WA。。。因为它有规定子序列长度不能超过n,心想有没有什么简单的方法可以快速判断,然而水平太菜一时间想不到,还是老老实实枚举判断左右端点吧。。。
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+1;
typedef long long ll;
ll dp[maxn],sum,a[maxn],size[maxn],ans,cnt;
int main()
{
int T,n,flag;
scanf("%d",&T);
while(T--)
{
flag=cnt=ans=sum=0;
memset(dp,0,sizeof(dp));
scanf("%d",&n);
for(int i=1;i<=n;++i)
{
scanf("%lld",&a[i]);
sum+=a[i];
}
int left=1;
for(int i=1;i<=n;++i)
{
if(dp[i-1]+a[i]>a[i]) dp[i]=dp[i-1]+a[i];
else {
dp[i]=a[i];
left=i;
}
size[i]=left;
}
for(int i=1;i<=n;++i)
{
//cout<<dp[i]<<endl;
if(dp[i]>sum) {
flag=1;printf("NO\n");break;
}
if(dp[i]==sum&&!(size[i]==1&&i==n)) {
flag=1;printf("NO\n");break;
}
}
if(!flag) printf("YES\n");
}
}