1692 子集和的目标值
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 钻石 Diamond
题目描述 Description
给定n个整数in和目标值T,求某一非空子集使 子集的元素的和 与 目标值之差 的绝对值最小,元素可重复
输入描述 Input Description
第一行为整数n T
n为整数个数,T为目标值
第二行为n个整数in
输出描述 Output Description
一个整数d,为差的最小值的绝对值
样例输入 Sample Input
5 9
1 1 1 4 17
样例输出 Sample Output
2
数据范围及提示 Data Size & Hint
1<=n<=101
0<=T<=2147483647
0<=in<=2147484647
放心,n很大的时候数据都很弱……
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
/*尽管这个题的标签是背包dp 但我一看数据范围这么大,还要加毛线特盘啊之类的,麻烦不会写,就果断搜了。 简单的dfs就好,不会T。 */ #include<cstdio> #include<cmath> #include<iostream> #include<map> #include<algorithm> using namespace std; int n,T,num[105],ans=2147483647; map<int,bool>f[105]; void dfs(int x,int tot) { if(x==n+1)ans=min(ans,abs(T-tot)); else { if(f[x][tot]||tot-T>ans)return; f[x][tot]=true;ans=min(ans,abs(T-tot)); dfs(x+1,tot);dfs(x+1,tot+num[x]); } } int main() { scanf("%d%d",&n,&T); for(int i=1;i<=n;i++) scanf("%d",&num[i]); dfs(1,0);printf("%d",ans); return 0; }