TCSRM 591 div2(1000)(dp)

挺好的dp 因为有一点限制 必须任意去除一个数 总和就会小于另一个总和 换句话来说就是去除最小的满足 那么就都满足

所以是限制最小值的背包 刚开始从小到大定住最小值来背 TLE了一组数据 后来发现如果从大到小的话 就不用多加一重for了  前面算的已经记录下来 直接用就OK了 

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #include<vector>

 7 using namespace std;

 8 #define LL long long

 9 #define N 3000010

10 LL dp[N],sum[N];

11 int a[55],b[55];

12 bool cmp(int a,int b)

13 {

14     return a>b;

15 }

16 class YetAnotherTwoTeamsProblem

17 {

18     public:

19     long long count(vector <int> skill)

20     {

21         int i,j,k,n;

22         for(i = 0 ; i < (int)skill.size() ; i++)

23         a[i+1] = skill[i];

24         LL ss=0,s=0;

25         n = (int)skill.size();

26         for(i = 1 ;i <= n ;i++)

27         {

28             s+=a[i];

29         }

30         sort(a+1,a+n+1,cmp);

31         for(i = 1 ; i <= n ;i++)

32         sum[i]=sum[i-1]+a[i];

33         LL v = (s+1)/2;

34         LL vv = s/2;

35         dp[0] = 1;

36         for(i = 1; i < n ;i++)

37         {

38             for(k = v-1 ; k >= a[i] ; k--)

39             {

40                 dp[k]+=dp[k-a[i]];

41             }

42             if(a[i]>vv)

43             ss+=1;

44             int tt;

45             if(vv-a[i+1]+1<0)

46             tt = 0;

47             else

48             tt = vv-a[i+1]+1;

49             for(j = tt ; j < v ;j++)

50             ss+=dp[j];

51         }

52         return ss;

53     }

54 };
View Code

 

你可能感兴趣的:(div)