演算法學習之路|幼兒園買玩具

kissjz發表於2018-02-24

題目大意
蒜廠幼兒園有 nn 個小朋友,每個小朋友都有自己想玩的玩具。身為幼兒園園長的你決定給幼兒園買一批玩具,由於經費有限,你只能買 mm 個玩具。已知玩具商店一共賣 kk 種玩具,編號為 1,2,3,…k1,2,3,…k,你讓每個小朋友把想玩的玩具編號都寫在了紙上。你希望滿足儘可能多的小朋友的需求,請計算出最多能滿足多少個小朋友的玩具需求。

輸入格式
第一行,輸入三個整數 n,m,k(1≤n≤100,1≤m≤k≤15)n,m,k(1≤n≤100,1≤m≤k≤15),中間用空格分開。

接下來 nn 行,第 i+1(0≤i

輸出格式
輸出一個整數,表示最多能滿足多少小朋友的玩具需求。

樣例輸入
5 3 5
2 1 4
0
2 3 1
3 2 3 4
2 4 5
樣例輸出
3
具體思路

我們可以列舉n,列舉出滿足最多孩子時,哪些孩子滿足了。可是n的範圍過於龐大,我們改變思路。

列舉所有種你可能取的玩具種類,每一種都求出可以滿足多少孩子,選擇能滿足孩子數最多的。

#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
int main(){
    int n,m,k;
    cin>>n>>m>>k;
    int a[100][16];//a[n][0]存每個人需要玩具的種類個數,a[n][1~15]存編號
    for(int i=0;i<n;i++){
        cin>>a[i][0];
        for(int j=1;j<=a[i][0];j++)
            cin>>a[i][j];
    }
    //以上錄入
    int MAX=0;
    
    for(int i=1;i<(1<<k);i++){//因為範圍n>>k,我們列舉k
        set<int> v;//列舉滿足最大人數時,玩具的所有種類
        for(int j=0;j<k;j++){//搜尋二進位制k位
            if(i&(1<<j))
                v.insert(j+1);
        }
        if(v.size()>m)  continue;//如果k的種類大於我們的m,跳過
        
        int num=0;//存列舉的每一種滿足的最大人數
        for(int j=0;j<n;j++){
            int flag=0;
            for(int k=1;k<=a[j][0];k++){
                if(v.find(a[j][k])==v.end()){
//如果孩子所需的不在此種中,這個孩子我們滿足不了,flag=1,不加入總和
                    flag=1;
                    break;
                }
            }
            if(flag==0)//說明該孩子的滿足我們這種玩具剛好滿足,加入總和
                num++;
        }
        MAX=max(MAX, num);//求列舉所有玩具中,滿足最大孩子數人數
    }
    cout<<MAX;
}


相關文章