链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
题目描述
小红拿到了一个数组,她每次可以进行如下操作之一:
·选择一个元素x,将其分裂为1和x−1。
·选择一个元素x,将其分裂为a和b,需要保证a∗b=x
小红希望用最少的操作次数,将所有数组的所有元素全部变成1。你能帮帮她吗?
输入描述:
第一行输入一个正整数n,代表数组的长度。 第二行输入nnn个正整数ai,代表小红拿到的数组。 1≤n,ai≤10^5
输出描述:
一个整数,代表最小的操作次数。
示例1
输入
2 2 6输出
5
说明
第一次,对第一个元素进行第一个操作,数组变成[1,1,6]。 第二次,对第三个元素进行第二个操作,数组变成[1,1,2,3]。 第三次,对第三个元素进行第一个操作,数组变成[1,1,1,1,3]。 第四次,对第五个元素进行第一个操作,数组变成[1,1,1,1,2,1]。 第五次,对第五个元素进行第一个操作,数组变成[1,1,1,1,1,1,1]。
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
//记忆化+动态规划?
// f [ i ] :把 i 分裂为全是 1 的数列所用的最短次数
import java.util.ArrayList;
import java.util.Scanner;
public class Main {
public static void main(String args[]) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int[] m=new int[n];
int index=0;
int sum=0;
int max=Integer.MIN_VALUE;
while(n>0){
n--;
int a=scan.nextInt();
m[index]=a;
index++;
max=Math.max(max,a);
}
int[] f=new int[max+1];
f[2]=1;
for(int i=3;i<=max;i++){
f[i]=f[i-1]+1;
for(int j=2;j*j<=i;j++){
if(i%j==0){
f[i]=Math.min(f[i],f[j]+f[i/j]+1);
}
}
}
for(int i=0;i<m.length;i++){
sum+=f[m[i]];
}
System.out.println(sum);
}
}
7369

被折叠的 条评论
为什么被折叠?



