【洛谷 P2080】增进感情(背包DP)

题目背景

小明和小红的感情,是慢慢发展起来的。

题目描述

他们对对方分别有一个好感值。定义两人的亲密程度为两人的好感值之和。

如果他们的亲密程度达到V,则他们将走到一起。他们以后的生活将取决于两人的好感值之差的绝对值,这个值越小,他们的生活将越幸福。

现在,他们对对方的好感值都为0,小明有N件事可以干,每件事可以增加他对小红的好感Ai点,并且增加小红对他的好感Bi点。(可能为负数)

小明可以任选一些事做,请你帮小明求出怎样才能让他们的生活更加幸福(求出两人在一起的前提下,好感值之差的最小绝对值即可)。

输入输出格式

输入格式:

第1行,两个正整数N,V。

之后N行,每行两个空格隔开的整数Ai,Bi。

输出格式:

一行,一个非负整数,表示两人在一起的前提下,好感值之差的最小绝对值。如果无论如何两人也无法在一起,输出-1.

把每件事情好感值之和转换为事情的价值,把差转化为事情的花费,这样问题就成了一个普通的背包DP。因为好感值之差的绝对值最小为0,所以当发现好感值之和大于亲密程度且差的绝对值为0可以直接输出。

 1 #include <cstdio>
 2 #include <cmath>
 3 
 4 using std::abs;
 5 #define INF 0x7ffffff
 6 
 7 int n,vmax,sum,a,b,w[31],v[31],f[6200],ans=INF;
 8 #define min(x,y) (abs(x)<abs(y)?x:y)
 9 
10 int main(void){
11     scanf("%d%d",&n,&vmax);
12     for(int i=1;i<=n;++i){
13         scanf("%d%d",&a,&b);
14         w[i]=a+b;
15         v[i]=a-b;
16         if(a+b>0)sum+=a+b;
17     }
18     for(int i=1;i<=sum;++i)
19         f[i]=INF;
20     for(int i=1;i<=n;++i){
21         for(int j=sum;j>=w[i];--j){
22             f[j]=min(f[j],f[j-w[i]]+v[i]);
23             if((f[j]==0)&&(j>=vmax)){
24                 printf("0");
25                 return 0;
26             }
27         }
28     }
29     for(int i=vmax;i<=sum;++i)
30         ans=min(ans,abs(f[i]));
31     printf("%d",ans==INF?-1:ans);
32 }

 

posted @ 2018-07-27 11:00  gzh01  阅读(245)  评论(0编辑  收藏  举报