其他分享
首页 > 其他分享> > 洛谷P8183题解

洛谷P8183题解

作者:互联网

本文同步更新于洛谷博客

题目描述

给定序列 \(\{a_n\}\),每次操作可以合并相邻的两个数,求使得序列中所有数相等的最小操作次数。

题解

设 \(\displaystyle\sum_{i=1}^n a_i=s\),因为合并不会影响 \(s\),所以我们可以枚举 \(s\) 的因数作为最后序列中的数值。
假设 \(x\) 为 \(s\) 的某个因数,从左到右进行如下操作:若 \(res<x\),则让 \(res\) 加上当前数;若 \(res=x\),则将 \(res\) 清零,即前面枚举的数合并成 \(x\);若 \(res>x\),则此种情况不可行。
最后,由于要求最小操作次数,所以我们要让每个数尽量的小,将 \(s\) 的因数从小到大枚举,一找到答案 break 即可。

Code

#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int t,n,s,cnt,a[maxn],p[1005],res,ans;
bool flag;
int main()
{
    scanf("%d",&t);
    while(t--)
    {
        flag=ans=cnt=s=0;
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
	    scanf("%d",&a[i]);
	    flag|=(a[i]!=a[1]);
	    s+=a[i];
	}
	if(!flag)
	{
	    printf("0\n");
	    continue;
	}
	for(int i=1;i<=s;i++)
	{
	    if(s%i)
		continue;
	    p[++cnt]=i;
	}
	for(int i=1;i<=cnt;i++)
	{
	    res=ans=0;
	    for(int j=1;j<=n;j++)
	    {
	        res+=a[j];
		ans++;
		if(res==p[i])
		{
		    res=0;
		    ans--;
		}
		if(res>p[i])
		    goto L;
	    }
	    break;
	    L:;
        }
        printf("%d\n",ans);
    }
    return 0;
}

标签:cnt,洛谷,int,题解,因数,ans,序列,P8183
来源: https://www.cnblogs.com/Gingerhe/p/15966083.html