将数组分为三部分(递归)

Divide an array into Three parts (Recursion)

本文关键字:三部 递归 数组      更新时间:2023-10-16

问题链接:

https://www.hackerearth.com/problem/algorithm/divide-to-three-33/description/

我能够使用动态编程来解决它。https://www.hackerearth.com/submission/1720148/

有人可以解释我的编辑解决方案(递归)。

编辑解决方案:

#include<cstdio>
#include<cstdio>
#include<queue>
#include<cstring>
#include<vector>
#include<iostream>
#include<string>
#include<algorithm>
#include<fstream>
#include<sstream>
using namespace std;
typedef long long int int64;
int64 n,a[40],ans,vl;
void fn(int64 i,int64 j,int64 k,int64 ptr){
    if(ptr==n){
        vl = max(max(i,j),k);if(vl<ans)ans=vl;
    }
    else{
        fn(i+a[ptr],j,k,ptr+1);
        fn(i,j+a[ptr],k,ptr+1);
        fn(i,j,k+a[ptr],ptr+1); 
    }
}
int main(){
//freopen("in3.txt","r",stdin);
//freopen("out3.txt","w",stdout);
    int64 i,j,k,l,m,t,vl,fl;ans=1000000;
    cin>>n;for(i=0;i<n;i++)cin>>a[i];
    fn(0,0,0,0);
    printf("%lldn",ans);
    return 0;
}

谢谢

Idea 非常简单,您可以将元素添加到三个集合(S1 或 S2 或 S3)中的任何一个。fn使用该功能,编码器基本上就是这样做的。查找一个表示为 ny ptr (元素为 a[ptr] ) 的元素,它要么被添加到 first( i ),second( j ) 或 last( k )。其中最大值作为输出给出。

实际上,将元素添加到三个集合中的任何一个的所有可能性都通过这三行进行检查

    fn(i+a[ptr],j,k,ptr+1);
    fn(i,j+a[ptr],k,ptr+1);
    fn(i,j,k+a[ptr],ptr+1);

基本条件显然是当我们完成检查数组中的所有 elemet 时

if(ptr==n){
    vl = max(max(i,j),k);if(vl<ans)ans=vl;
    }

max(max(i,j),k) 中找到最多三个集合和。

现在if(vl<min)将确定满足条件的最低S1。这就是为什么这个检查是v1<ans,我们将尽量减少S1

这里的 i,j,k 表示相应集合的总和。