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

时间:2015-04-18 11:09:35

标签: c++ arrays recursion dynamic-programming partition

问题链接:

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("%lld\n",ans);

    return 0;
}

谢谢,

1 个答案:

答案 0 :(得分:0)

想法非常简单,您可以将元素添加到三个集合中的任何一个(S1或S2或S3)。使用函数fn,编码器基本上就是这样做了。看一个表示为ny ptr的元素(元素是a[ptr]),它被添加到第一个(i),第二个(j)或最后一次(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);

基础条件显然是在我们完成检查数组中的所有元素时

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表示相应集合的总和。