Time Limit: 500MS
Memory Limit: 65536KB
Total Submit: 343
Accepted: 96
Special Judge: No
Description
Today, Alice got her math homework again!
She had
n integers, and she needed to
divide them into several piles or one pile. For each pile, if the teacher could get
S,
by + or – operator, then Alice got
1 small red flower. Alice wanted to get
as many flowers
as possible. Could you help her? Just tell her the
maximum number of flowers she could get.
Input
The input consists of several test cases.
The first line consists of one integer T (T <= 100), meaning the number of test cases.
The first line of each test cases consists of two integer n (n<=14), meaning the number of the integer, and S (0<= S<= 100000000), meaning the result which teacher wanted.
The next line consists of n integer a1, a2, …, an (0<= ai <= 10000000).
You should know a few cases that n is larger than 12.
Output
For each test case, output one line with one integer without any space.
Sample Input
2
5 5
1 2 3 4 5
5 5
1 2 3 8 8
Sample Output
3
2
Hint
Source
分析: 于是比赛时我又煞笔了。。。记忆化搜索T了,直接暴力DP反而更快。。
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;
int f[1<<14],sum[1<<14],n,m,s,t,ans,a[15];
bool jud[1<<14];
int main()
{
cin.sync_with_stdio(false);
cin>>t;
for(int T=1;T <= t;T++)
{
cin>>n>>s;
int N=(1<<n)-1;
memset(sum,0,sizeof(sum));
memset(f,0,sizeof(f));
memset(jud,0,sizeof(jud));
for(int i=1;i <= n;i++) cin>>a[i];
for(int i=N;i;i=(i-1) & N)
{
for(int j=0;j < n;j++)
if(i & (1<<j)) sum[i]+=a[j+1];
if(sum[i] == s) jud[i]=true;
}
for(int i=N;i;i=(i-1) & N)
if(!jud[i])
for(int j=i;j;j=(j-1) & i)
if(sum[i]-2*sum[j] == s)
{
jud[i]=true;
break;
}
for(int i=0;i <= N;i++)
for(int j=i;j;j=(j-1) & i)
if(jud[j]) f[i]=max(f[i],1+f[i-j]);
cout<<f[N]<<endl;
}
}