UOJ Logo sharpland的博客

博客

[P1545讨论帖] 【P1545解题讨论】新讨论

2021-06-21 09:56:01 By sharpland

一眼看到这道题,一个DFS的思路来了,但是本蒟蒻连普及都没有考,水平很低,大佬们的记忆化搜索都不会。。

好了,先说一下思路,本蒟蒻外面用一个for循环来代表选取材料的数量,将这个数量当做参数。

然后,说一下坑点:

这个题目要看清了,我们知道它们各自的酸度S和甜度B。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的甜度为每一种配料的甜度的总和。

然后,我们必须添加至少一种配料。。

下面,看代码(逃)

#include<bits/stdc++.h>
using namespace std;
//n为配料个数,minn为最小值,x为酸度(注意声明=1啊),y为甜度
int n,minn,x=1,y;
//a存储酸度,b存储甜度
int a[11],b[11];
//用来标记用过的数
int book[11];
//传的参数代表选配料的个数,刚才忘了说了
void dfs(int c){
    //如果c是0,代表选完了,那么寻找最小值,并返回到上一次查找
    if(c==0){
        minn=min(minn,abs(x-y));
        return;
    }
    //从1到n查找
    for(int i=1;i<=n;i++){
    //是否使用过,没有使用过,即可使用
        if(book[i]){
        //将book[i]改为0,避免重复使用
            book[i]=0;
            //x增加
            x=a[i];
           //y增加
            y+=b[i];
            //剩余寻找次数减少
            c--;
            //继续搜索
            dfs(c);
            //别忘记恢复现场啊,否则答案是错误的
            c++;
            x/=a[i];
            y-=b[i];
            book[i]=1;
        } 
    }
}
int main(){
   //输入不解释
    ios::sync_with_stdio(false);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i]>>b[i];
    //选择所有配料的情况
    for(int i=1;i<=n;i++){
    //注意乘法
        x=a[i];
       //加法
        y+=b[i];
    }
    //abs是取绝对值,大家都知道吧,例如(-2)的绝对值是2
    minn=abs(x-y);
    //只选择一种配料的情况
    for(int i=1;i<=n;i++)
    //min方法取最小值,这样可以将最小值复制给minn
        minn=min(minn,abs(a[i]-b[i]));
        //选2~n中一种配料的情况
    for(int i=2;i<n;i++){
    //初始化不解释
        memset(book,1,sizeof(book));
      //别忘了重新初始化
        x=1;
        y=0;
        //神搜
        dfs(i);
    }
    //输出
    cout<<minn;
    return 0;
}

最后,有几个方法给初学者讲一下:

1、ios::sync_with_stdio(false);这个方法还是要解释一下的

在某些题目中,我们使用普通的cin和cout会超时,所以我们每次只能打scanf和printf,然后一堆的占位符巨麻烦),为什么cin和cout比scanf和printf用的时间多? 这是因为C++中,cin和cout要与stdio同步,中间会有一个缓冲,所以导致cin,cout语句输入输出缓慢,这时就可以用这个语句,取消cin,cout与stdio的同步,说白了就是提速,效率基本与scanf和printf一致。

2、abs绝对值

abs 是 absolute value (绝对值)缩写。c++ 中的一个数学函数,计算整型量的绝对值。要头文件 #include <cmath> 或 #include <math.h>

算例:
int x=16, y= -6;
cout << abs(x) << endl;
cout << abs(y) << endl;
输出:
16
6

但是注意浮点数要使用fabs

3、min取最小值

例如:

int a=10,b=8;
cout<<min(a,b);

则这段代码会输出8

4、memset

memset是计算机中C/C++语言初始化函数。作用是将某一块内存中的内容全部设置为指定的值, 这个函数通常为新申请的内存做初始化工作。

例如:

int a[100001]={1,43,3,2,3,5};
memset(a,0,sizeof(a));

那么a数组所有位置都为0

编程语言 C++ 代码长度 906B 用时 424ms 内存 668.00KB

有帮助的,记得点个赞哈!!

评论

暂无评论

发表评论

可以用@mike来提到mike这个用户,mike会被高亮显示。如果你真的想打“@”这个字符,请用“@@”。