可达性DP
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,k;
int a[12341],sum,mi=10000000;
bool f[112][46000];
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
f[0][0]=1;
for(int i=1;i<=n;i++){
for(int j=(n+1)/2-1;j!=-1;j--){//完全背包倒序循环
int lp=min(450*i,sum);
for(int k=lp;k>=0;k--){//完全背包倒序循环
if( f[j][k] && (k+a[i])<=lp )f[j+1][k+a[i]]=1;
}
}
}
int mk,sub=10000000;
for(int k=1;k<=sum;k++){
if(f[(n+1)/2][k] && abs(2*k-sum)<sub){//用2*k 代替 除以2
sub=abs(2*k-sum);
mk=k;
}
}
cout<<min(mk,sum-mk)<<' '<<max(mk,sum-mk);
}
随机化贪心
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
using namespace std;
int n,k,a1,a2,ans;
int a[12341],sum,mi=10000000;
void randomdf()
{
for(int i = 1;i <= n;i ++)
{
int p = rand()%n+1;//rand()%n+1;
swap(a[i],a[p]);//a[i]
}
}
int main(){
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
sum+=a[i];
}
if(n&1)a1=a[(n+1)/2];
srand(926);
int lp=300000,sub=1000000;
while(lp){
lp--;
randomdf();
a1=a2=0;
for(int i=1;i<=(n/2);i++){
a1=min(a1,a2)+max(a[i],a[n-i+1]);
a1=max(a1,a2)+min(a[i],a[n-i+1]);
}
if(abs(2*a1-sum)<sub){
sub=abs(2*a1-sum);
ans=a1;
}
if(abs(2*a2-sum)<sub){
sub=abs(2*a2-sum);
ans=a2;
}
}
cout<<min(sum-ans,ans)<<' '<<max(sum-ans,ans);
}
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
#include<cmath>
#include<ctime>
#include<cstdlib>
#define itn int
#define Endl endl
using namespace std;
typedef long long ll;
const int size = 1000010;
ll lans,rans,lp,rp;
int num[size],n;
void randomm()
{
for(int i = 1;i <= n;i ++)
{
int p = rand()%n+1;
swap(num[i],num[p]);
}
}
ll llans,rrans,minc = 2 << 28;
int main()
{
srand((unsigned)(clock()));
scanf("%d",&n);
for(int i = 1;i <= n;i ++) scanf("%d",&num[i]);
// sort(num+1,num+1+n);
for(int i = 1;i <= 100000;i ++)
{
randomm();
lans = (ll)(num[n]);
rans = 0;
lp = 1;
rp = 0;
for(int i = n-1;i > 0;i --)
{
if(lans > rans)
{
rans += (ll)(num[i]);
rp ++;
if(rp - lp - 1 == i - 1 || rp-lp == i-1)
{
for(int j = i-1;j > 0;j --)
{
lans += (ll)(num[j]);
}
break;
}
}
else
{
lans += (ll)(num[i]);
lp ++;
if(lp - rp - 1 == i - 1 || lp - rp == i - 1)
{
for(int j = i-1;j > 0;j --)
{
rans += (ll)(num[j]);
}
break;
}
}
}
if(lans > rans) swap(lans,rans);
if(rans-lans < minc)
{
llans = lans;
rrans = rans;
minc = rans-lans;
}
}
printf("%lld %lld",llans,rrans);
system("pause");
return 0;
}
/*
20
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 190
*/