P2036 [COCI2008-2009#2] PERKET

tech2024-02-19  67

题目描述

Perket 是一种流行的美食。为了做好 Perket,厨师必须谨慎选择食材,以在保持传统风味的同时尽可能获得最全面的味道。你有 nn 种可支配的配料。对于每一种配料,我们知道它们各自的酸度 ss 和苦度 bb。当我们添加配料时,总的酸度为每一种配料的酸度总乘积;总的苦度为每一种配料的苦度的总和。

众所周知,美食应该做到口感适中,所以我们希望选取配料,以使得酸度和苦度的绝对差最小。

另外,我们必须添加至少一种配料,因为没有任何食物以水为配料的。

输入格式

第一行一个整数 nn,表示可供选用的食材种类数。

接下来 nn 行,每行 22 个整数 s_isi​ 和 b_ibi​,表示第 ii 种食材的酸度和苦度。

输出格式

一行一个整数,表示可能的总酸度和总苦度的最小绝对差。

输入输出样例

输入 #1复制

1 3 10

输出 #1复制

7

输入 #2复制

2 3 8 5 8

输出 #2复制

1

输入 #3复制

4 1 7 2 6 3 8 4 9

输出 #3复制

1

说明/提示

数据规模与约定

对于 100\%100% 的数据,有 1 \leq n \leq 101≤n≤10,且将所有可用食材全部使用产生的总酸度和总苦度之和小于 1 \times 10^91×109。

 

思路: 这题简单搜索我用来练练状态压缩,嘻嘻

例如  二进制   00101 (从右往左,下标从0开始)表示选择了第0,2种食材,1表示选中,0表示不选。

再用上位运算,(i>>j)&1 表示判断 状态i的第j位是否选中。i>>j 截取 i二进制的第j位

#include<bits/stdc++.h> using namespace std; const int m=30; int s[m],b[m],c[m],minn,n,vis[m]; int main(){ int ss,bb; cin>>n; for(int i=0; i<n; i++){//下标从0开始 cin>>s[i]>>b[i]; } minn=0x7fffffff; for(int i=1; i<(1<<n); i++){ ss=1,bb=0; for(int j=0; j<n; j++){ if((i>>j)&1){//判断第j种是否选中,下标从0开始 ss*=s[j]; bb+=b[j]; } } minn=min(minn,abs(ss-bb)); } cout<<minn<<endl; return 0; }

 

最新回复(0)