codevs 1692 子集和的目标值

真是佩服出这题的人。

1.首先基本思路:考虑对T与SUM-T分别进行背包,再min起来。为什么呢?难点在于SUM-T的是考虑有哪些数没有被选。

2.然后数据范围???瞬间吓尿。幸好有出题人指点,考虑分治。

3.然后??细节比较烦。对于abs的和T=0的特判需要注意。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
long long n,t,num[105];
long long f[10000005],sum=0,kk=9999999999,rr=9999999999;
long long abs(long long a)
{
if (a<0) return -a;
return a;
}
long long dp(long long x)
{
memset(f,0,sizeof(f));
for (long long i=1;i<=n;i++)
for (long long j=x;j>=num[i];j--)
f[j]=max(f[j],f[j-num[i]]+num[i]);
return f[x];
}
void dfs(long long x,long long now)
{
if (x==n+1)
{
kk=min(kk,abs(now-t));
return;
}
else
{
dfs(x+1,now);
dfs(x+1,now+num[x]);
}
}
int main()
{
scanf("%lld%lld",&n,&t);
for (int i=1;i<=n;i++)
{
scanf("%lld",&num[i]);
sum=sum+num[i];
rr=min(rr,num[i]);
}
if (t==0) printf("%lld\n",rr);
else if (t<10000000)
{
long long minn=12345678;
minn=min(minn,abs(t-dp(t)));
minn=min(minn,abs(sum-t-dp(sum-t)));
printf("%lld\n",minn);
}
else
{
dfs(1,0);
printf("%lld\n",kk);
}
return 0;
}

时间: 2024-07-31 14:23:36

codevs 1692 子集和的目标值的相关文章

子集和的目标值(codevs 1692)

题目描述 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<

suseoj 1211: 子集和问题 (dfs)

1211: 子集和问题 时间限制: 1 Sec  内存限制: 128 MB提交: 2  解决: 2[提交][状态][讨论版][命题人:liyuansong] 题目描述 子集和问题的一个实例为<S,t>.其中,S={x1,x2,...,xn}是一个正整数的集合,c是一个正整数.子集和问题判定是否存在S的一个子集S1,使得 试设计一个解子集和问题的回溯法. 对于给定的正整数的集合S和正整数c,计算S的一个子集S1使得 输入 第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值.接下来的1行

ACM-Subset sum

题目描述: Subset Sum Tags: 回溯 子集和问题的一个实例为〈 S,t 〉.其中,S={x1 ,x2 ,…, xn }是一个正整数的集合,c是一个正整数.子集和问题判定是否存在S的一个子集S1,使得x1+x2+...+xk=S, 其中x1,x2...xk属于集合S1. 对于给定的正整数的集合S和正整数c,编程计算S 的一个子集S1,使得x1+x2+...+xk=S, 其中x1,x2...xk属于集合S1. 输入 第1 行有2 个正整数n 和c,n 表示S 的大小,c是子集和的目标值

第五章实践报告

1.实践题目:工作分配问题 2.问题描述: 设集合S={x1,x2,-,xn}是一个正整数集合,c是一个正整数,子集和问题判定是否存在S的一个子集S1,使S1中的元素之和为c.试设计一个解子集和问题的回溯法. 输入格式: 输入数据第1行有2个正整数n和c,n表示S的大小,c是子集和的目标值.接下来的1行中,有n个正整数,表示集合S中的元素. 是子集和的目标值.接下来的1 行中,有n个正整数,表示集合S中的元素. 输出格式: 输出子集和问题的解,以空格分隔,最后一个输出的后面有空格.当问题无解时,

codevs 3152 装箱问题3

装箱问题3 http://codevs.cn/problem/3152/ 题目描述 Description 设有n种物品,记作A1.A2.-.An,对应于每个Ai(1<=i<=n)都有一个重量Awi和价值Avi(重量和价值都为正整数).另外,对应于每个Ai,都有一件可代替它的"代用品"Bi,Bi的重量和价值分别为Bwi和Bvi. 本题的任务是:选择这n件物品或其代用品的一个子集装进背包,使总重量不超过给定重量TOT,同时使总价值VAL最高.装填的第I步,要么装入Ai,要么装

codevs 1022 覆盖

题目链接:http://codevs.cn/problem/1022/ 题解: 匈牙利稍作改动,用邻接矩阵存储,以{横坐标和纵坐标都为奇数或横坐标和纵坐标都为偶数的点}为一个子集,其余的点为另一个子集,每次枚举4个方向进行深搜 1 #include<cstdio> 2 #include<cstring> 3 #define MAXN 110 4 int n,m,k,edge[MAXN][MAXN][2],ans; 5 bool used[MAXN][MAXN],map[MAXN][

0-1背包问题与子集合加总问题的近似算法

最近没有怎么更新博客,因为一直比较忙.最近发现所里在做的一个项目中,可以抽出一部分内容和0-1背包问题.子集合加总问题非常相似(虽然表面上不容易看出相似点),所以看了一些这方面的资料和论文,这里主要对问题特点和算法思想做一些整理.这类问题其实很有意思,做数学和做计算机的人都会研究,而且我这里将要提到的论文都是做计算机的人所写的. 问题简述0-1 Knapsack Problem (0-1背包问题,下面简称KP)和Subset Sum Problem (子集合加总问题,下面简称SSP)是经典的NP

416分割等和子集

题目:给定一个只包含正整数的非空数组.是否可以将这个数组分割成两个子集,使得两个子集的元素和相等.注意: 每个数组中的元素不会超过 100,数组的大小不会超过 200来源:https://leetcode-cn.com/problems/partition-equal-subset-sum/ 法一:动态规划 思路:首先写状态转移方程的时候,如果采用类似312戳气球的方法,即由内到外,由小到大,是难以实现的,原因有二,一是假如题目中的数组元素有6个,则dp[1]即长度为1的子集有6个,dp[2]长

[ CodeVS冲杯之路 ] P2492

不充钱,你怎么AC? 题目:http://codevs.cn/problem/2492/ 在此先orz小胖子,教我怎么路径压缩链表,那么这样就可以在任意节点跳进链表啦(手动@LCF) 对于查询操作,直接树状数组(以下简称BIT)维护,修改操作就一个个暴力开方搞,再用差值单点更新BIT 不过这样会TLE,要加一点优化对不对,正如开头所说的路径压缩链表 路径压缩链表其实就是个并查集,在普通的链表里,删去两个连续的节点后会是下面这种情况,如删去2,3 当访问 2 的时候,会跳到3,但 3 已经删除了,