洛谷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