zoukankan      html  css  js  c++  java
  • DP----luoguP1489猫狗大战

    题目大意:

    给你一个序列(长度小于等于200),你需要把它分成两半而且两个被分开的序列长度差不超过一(如果是偶数的话那么就必须是一样长咯)

    要求分成的两个序列的总和差的绝对值最小

    做题思路:

    1.既然是序列总和,而且分成两半,那么我为什么不先预处理出一开始整个序列的和呢?

    2.既然是两个序列的总和,那么必然会存在一个序列的总和小于等于另外一个序列的总和

    感性理解:两个里面肯定有一个大的咯

    3.那么我们不妨让那个小的尽可能接近总和的一半?问题就转化为了以整个序列的总和的一半为背包容量,而且限制一定要取n/2或者n/2+1个数(对其取max)?

    事实证明我的思路是正确的,但是比较假的就是我只有70分,大的数据点能过,但是有几个小的数据点反而过不了,我想下载数据但是下不了,也不知道自己为什么被hack了。。。

    #include <bits/stdc++.h>
    using namespace std;
    int n,a[350],sum=0;
    int dp[8005][105];
    int main(){
        cin>>n;
        for (int i = 1 ; i <= n ; i ++)cin>>a[i],sum+=a[i];
        for (int i = 1 ; i <= n; i ++)
            for (int k = n/2+1; k >= 1; k-- )
                for (int j = sum/2 ; j >= a[i] ; j --)        
            dp[j][k]=max(dp[j-a[i]][k-1]+a[i],dp[j][k]);
        
        if(n%2 ==0)cout<<dp[sum/2][n/2]<<" "<<sum-dp[sum/2][n/2];
        if(n%2 ==1){
            int ans=max(dp[sum/2][n/2],dp[sum/2][n/2+1]);
            cout<<ans<<" "<<sum-ans;
        }
        return 0;
    }
  • 相关阅读:
    Delphi公用函数单元
    Delphi XE5 for Android (十一)
    Delphi XE5 for Android (十)
    Delphi XE5 for Android (九)
    Delphi XE5 for Android (八)
    Delphi XE5 for Android (七)
    Delphi XE5 for Android (五)
    Delphi XE5 for Android (四)
    Delphi XE5 for Android (三)
    Delphi XE5 for Android (二)
  • 原文地址:https://www.cnblogs.com/MYCui/p/13541399.html
Copyright © 2011-2022 走看看