Problem
Takahashi, who is a novice in competitive programming, wants to learn MM algorithms. Initially, his understanding level of each of the MM algorithms is 00.
Takahashi is visiting a bookstore, where he finds NN books on algorithms. The ii-th book (1≤i≤N1≤i≤N) is sold for CiCi yen (the currency of Japan). If he buys and reads it, his understanding level of the jj-th algorithm will increase by Ai,jAi,j for each jj (1≤j≤M1≤j≤M). There is no other way to increase the understanding levels of the algorithms.
Takahashi's objective is to make his understanding levels of all the MM algorithms XX or higher. Determine whether this objective is achievable. If it is achievable, find the minimum amount of money needed to achieve it.
Constraints
- All values in input are integers.
- 1≤N,M≤121≤N,M≤12
- 1≤X≤1051≤X≤105
- 1≤Ci≤1051≤Ci≤105
- 0≤Ai,j≤1050≤Ai,j≤105
Input
Input is given from Standard Input in the following format:
NN MM XX
C1C1 A1,1A1,1 A1,2A1,2 ⋯⋯ A1,MA1,M
C2C2 A2,1A2,1 A2,2A2,2 ⋯⋯ A2,MA2,M
⋮⋮
CNCN AN,1AN,1 AN,2AN,2 ⋯⋯ AN,MAN,M
Output
If the objective is not achievable, print -1
; otherwise, print the minimum amount of money needed to achieve it.
Sample Input 1
3 3 10
60 2 2 4
70 8 7 9
50 2 3 9
Sample Output 1
120
Buying the second and third books makes his understanding levels of all the algorithms 1010 or higher, at the minimum cost possible.
Sample Input 2
3 3 10
100 3 1 4
100 1 5 9
100 2 6 5
Sample Output 2
-1
Buying all the books is still not enough to make his understanding levels of all the algorithms 1010 or higher.
Sample Input 3
8 5 22
100 3 7 5 3 1
164 4 5 2 7 8
334 7 2 7 2 9
234 4 7 2 8 2
541 5 4 3 3 6
235 4 8 6 9 7
394 3 6 1 6 2
872 8 4 3 7 2
Sample Output 3
1067
题解:
之前做这个题使用dfs做的,这次为了讲课用了二进制枚举,没想到更简单。
思路:
使用二进制枚举把所有购买书的方案都找出来,再进行比较就能得出答案了,简单又粗暴。
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct node
{
int c;//每本书的价格
int a[15];//这本书能够提升Ta的第j个算法多少等级
}book[15];//储存每一本书的信息
int b[15];//统计每个子集能够提升第j个算法的总的等级数
int main()
{
int n,m,x;
cin>>n>>m>>x;
for(int i=0;i<n;i++)
{
cin>>book[i].c;
for(int j=0;j<m;j++) cin>>book[i].a[j];
}
int ans=2e9;
for(int i=0;i<(1<<n);i++)
{
memset(b,0,sizeof b);
int sum=0;//统计每一个子集所有书的总价格
for(int j=0;j<n;j++)
if(i>>j&1)
{
sum+=book[j].c;
for(int k=0;k<m;k++) b[k]+=book[j].a[k];
}
bool flag=1;//判断m个算法是否都大于等于x,1为是,0为否
for(int j=0;j<m;j++) if(b[j]<x) flag=0;
if(flag) ans=min(ans,sum);//每次都选择更小价格
}
if(ans==2e9) cout<<"-1";
else cout<<ans;
return 0;
}