USACO 2.2 Subset Sums set (subset), USACO Subset
Description
For a continuous integer from 1 to N, it can be divided into two subsets, and the number of each set are equal.
For example, if N = 3, for {1, 2, 3}, it can be divided into two subsets, and all their numbers are equal:
This is the only method (the position of the exchange set is considered to be the same division scheme, so the total number of Division schemes will not be increased)
If N = 7, there are four ways to divide the set {1, 2, 3, 4, 5, 6, 7}. Each sub-set of each distribution has the same number and is equal:
- {1, 6, 7} and {2, 3, 4, 5} {Note 1 + 6 + 7 = 2 + 3 + 4 + 5}
- {2, 5, 7} and {1, 3}
- {3, 4, 7} and {1, 2, 5, 6}
- {1, 2, 4, 7} and {3, 5, 6}
Given N, your program should output the total number of Division schemes. If such a division scheme does not exist, it will output 0. The program cannot store the result and output it directly.
This is my first code in Ubuntu. I personally think that many of the interfaces in Ubuntu are also good in style )...
The general meaning of this dp is to give you one from each number of 1-N and ask you how many possibilities a + B + c... = x + y + z (of course, a, B, c, x, y, all belong to the n number) and these numbers must be used up and cannot be reused.
I just read the question, but I don't know how to use dp. It's obvious that it's a pitfall. I just went to baidu if I couldn't think of it (...) Then we can see that a common solution is to think of it as a 01 backpack and then"
If M = n * (n + 1)/2 is an odd number, there is no division. If it is an even number, the backpack capacity is M/2, dp [k] + = dp [k-I], (I = 1, 2 ,..., n) to avoid re-calculation when calculating k,
You need to proceed backwards ." (This is not difficult to understand. (Please forgive me for being stupid ))
Then I thought about [1, n] that all the numbers in this interval soon formed an equality SEQUENCE OF an = n. So according to the summation formula sn = n + n * (n-1) /2 = n * (n + 1)/2. In this case, the two sides must be equal.
L (the sum on the left) = r (the sum on the right) = n * (n + 1)/4 If the calculated n * (n + 1) if/4 is a decimal number, it is impossible to solve the problem. Therefore, you only need to determine whether n * (n + 1)/4 can be exhausted (that is, to determine whether n * (n + 1) % 4 is 0) and return directly if the Division is not complete.
After preliminary judgment, we will start to use the dp method. We can think of n items as n * (n + 1) /4 Quality This Time Division is equal to this time j is more than I, plus the original I Division
The Code is as follows:
1 #include<iostream> 2 using namespace std; 3 const int maxn=10000+10; 4 long long f[100000]; 5 int n,s; 6 int main() 7 { 8 cin>>n; 9 s=n*(n+1);10 if(s%4!=0)11 {12 cout<<0<<endl;13 return 0;14 }15 s/=4;16 f[0]=1;17 for(int i=1;i<=n;i++)18 for(int j=s;j>=i;j--)19 f[j]+=f[j-i];20 cout<<f[s]/2<<endl;21 return 0;22 }