USACO 2.2 Subset Sums

USACO 2.2 Subset Sums

动态规划经典题子集和问题。
求子集和为总数的一半的子集的个数,按题意,还要再除以2。
int会溢出,要用long long.第一次提交就没有注意到这个问题。


#include 
< iostream >
#include 
< fstream >

using   namespace  std;

ifstream fin(
" subset.in " );
ofstream fout(
" subset.out " );

#ifdef _DEBUG
#define  out cout
#define  in cin
#else
#define  out fout
#define  in fin
#endif

long   long  dp[ 800 ];

void  solve()
{

    
int  n;
    
in >> n;

    
int  sum  =  (n + 1 ) * n / 2 ;

    
if (sum & 1 ){
       // 和为奇数,无解
         out << 0 << endl;
        
return ;
    }

    sum
>>= 1 ;


    dp[
0 =   1 ;

    
for ( int  i = 1 ;i <= n; ++ i){
        
// 从后向前,空间复杂度就降为O(n)了,具体可参考<背包问题九讲>
         for ( int  t  =  sum;t >= i; -- t){
            dp[t]
+= dp[t - i];
        }
    }

    
out << dp[sum] / 2 << endl;
}

int  main( int  argc, char   * argv[])
{
    solve(); 
    
return   0 ;
}


你可能感兴趣的:(USACO 2.2 Subset Sums)