洛谷P2080 增进感情

增进感情

题目背景

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

题目描述

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

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

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

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

输入格式

第一行,两个正整数 n,v。

之后 n 行,每行两个空格隔开的整数 ai​,bi​。

输出格式

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

输入输出样例

输入 #1复制

4 15
5 6
-1 8
7 2
1 0

输出 #1复制

3

说明/提示

数据范围与约定
  • 对于20% 数据,保证n≤10。
  • 对于100% 数据,保证1≤n≤30,1≤∣ai​∣,∣bi​∣≤100。

代码: 

1.有两个点TLE

//记录每个点选或不选,最多有2^30次方选法,TLE
#include <bits/stdc++.h>
using namespace std;
int n,v;
int a[41],b[41];
int ans[41],s,s1;//ans存方案 s存绝对值之差 s1存好感度之和
int minn=1e6,f;//f判断是否能在一起
void dfs(int now,int d){//now判断这件事做不做 1代表做 0代表不做
    ans[d]=now;//存答案
    if(d==n){//如果判断完n件事情了
        s=0,s1=0;//初始化为0
        for(int i = 1;i<=n;i++){
            if(ans[i]==1){//如果做第i件事
                s+=a[i]-b[i];//先求每次好感值之差的和
                s1+=a[i]+b[i];//求每次好感值的和
            }
        }
        s=abs(s);//取绝对值
        if(s1>=v){//如果前提可以在一起满足
            f=1;//f=1代表至少可以在一起
            minn=min(minn,s);//得到好感值绝对值之差的最小值
        }
        return ;
    }
    dfs(0,d+1);//搜下一件事做不做
    dfs(1,d+1);
}
int main(){
    scanf("%d%d",&n,&v);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i],&b[i]);
    }
    dfs(0,0);
    if(f) printf("%d",minn);//如果f=1 可以在一起否则前提不满足输出-1
    else cout<< -1;
    return 0;
}

2.AC 

#include <bits/stdc++.h>
using namespace std;
int n,v;
int a[41],b[41];
int minn=1e6;
void dfs(int now,int sum1,int sum2){
    //now现在是第几件事 sum1到目前为止小明对小红的好感度之和 sum2到目前为止小红对小明的好感度之和
    if(sum1+sum2>=v){//如果两人可以在一起的前提满足,更新最小值
        minn=min(minn,abs(sum1-sum2));
    }
    for(int i = now+1;i<=n;i++){//悟
        dfs(i,sum1+a[i],sum2+b[i]);//如果下面看第i件事,那么和都加上第i件事影响的值
    }
}
int main(){
    scanf("%d%d",&n,&v);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i],&b[i]);
    }
    dfs(0,0,0);
    if(minn!=1e6) printf("%d",minn);//如果minn为1e6那么在一起的前提不满足
    else cout<< -1;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值