洛谷之PERKET

洛谷P2036 [COCI2008-2009#2] PERKET

https://www.luogu.com.cn/problem/P2036

先分析题目,题目中有n种食材,每食材有酸度和苦度,然后要求选取食材,使酸度和苦度绝对值差最小,其中酸度是相乘,苦度是相加。

很明显 ,题目的意思是要我们算出所有绝对值差,然后找出里面最小的,既然是求最小值,我第一反应想到的就是C++里algorithm里的min函数,可以直接帮我们计算两个值中的最小值,既然是算出所有绝对值差,那么肯定是用搜索啦!

下面放代码:

#include <iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
using namespace std;
#define MAXN 0x3f3f3f;
struct MS
{
    int x;
    int y;
}T[100000];//首先定义结构体
int s = 1, k = 0;
int n;
int sum = 0x3f3f3f3f;
bool vis[100000];//判断是否走过
void dfs(int start, int total)//深搜,start表示开始搜的点,total表示酸度和苦度的和
{
  
    sum = min(total, sum);//c++中min函数 需要头文件algorithm。
    if (start > n)//如果start>n,即搜索的点比食材数目大,返回上一步
        return;
    for (int i = 1; i <= n; i++)
    {
        if (!vis[i])//如果点不为空
        {
            s *= T[i].x;/酸度相乘
            k += T[i].y;//苦度相加
            vis[i] = 1;//标记点已经走过
            total = abs(s - k);//总和等于酸度减去苦度的绝对值 abs表示计算绝对值,在math头文件中
            dfs(i + 1, total);//搜索下一个食材。
            s /= T[i].x;//这里是回溯 就是从1开始搜到底之后,回溯到之前初始状态,从2搜到底,以此类推。
            k -= T[i].y;
            vis[i] = 0;
        }
    }
}
int main()
{

    cin >> n;
    memset(vis, 0, sizeof(vis));
    for (int i = 1; i <= n; i++)
    {
        cin >> T[i].x >> T[i].y;
    }
    dfs(1, 100000);
    cout << sum;
}
posted @ 2020-09-06 09:50  故犹  阅读(223)  评论(0编辑  收藏  举报