1959 拔河比賽[DP][隨機化貪心※]

可達性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
*/
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章