強迫症的喫貨

曉萌作爲一個營養學專家,喫東西的時候總是要考慮是否能滿足他的各種營養物質需求,大家都說他是一個有強迫症的喫貨。曉萌知道每種食品中營養物質的含量,請你幫他安排食譜,以保持他獲得所需營養物質的同時,喫的食品的種類最少。(營養物質含量爲整數,每種食品曉萌只吃一次)。

輸入第1行爲一個整數V表示曉萌需要的營養物質的種類數(1≤V≤25)。

輸入第2行包括用空格分隔開的V個整數,依次表示每種營養物質的需求量(1≤每個整數≤1000)。

輸入第3行包括一個整數ģ表示提供可以給曉萌喫的食品的種類數(1≤G≤15)。

接下來的ģ行,每行包括用空格分隔開的V個整數,G行中的第我行中V個整數依次表示第我種食品中每種營養物質的需求量(1≤每個整數≤1000)。

輸出包括空格分隔的多個數,第一個數爲必需的最小的食品種數P:後面有P個數,表示所選擇的食品編號(按從小到大排列);如果有多個解,輸出食品序號最小的(即字典序最小)。

樣例輸入

4
100 200 300 400
3
50 50 50 50
200 300 200 300
900 150 389 399

樣例輸出

2 1 3

題解:用枚舉的方式來測試每次最小的食物種數P,然後再用DFS的方式,從第一種提供的食物開始,這樣DFS後的正確結果就是排好序的;

#include<iostream>
#include<cstring>
using namespace std;
int a[30],b[20][30],c[30],d[30],f[30],n,m,x,y,k,z=0,ans=0;
bool key=false;
void dfs(int t,int u)
{
    if(u>=k||t>=m)//深搜結束的條件(添加的食物超過枚舉或者深搜開始的地方已經超出食物種類範圍)
    {
        return;
    }
    for(int i=0;i<n;i++)//(將當前位置的食物營養含量加入總和)
    {
        c[i]+=b[t][i];
    }
    d[u]=t;(記錄選擇的位置)
    key=true;
    for(int i=0;i<n;i++)//判斷是否符合條件
    {
        if(c[i]<a[i])
        {
            key=false;
        }
    }
    if(key==true&&z==0)//只有第一次符合條件的答案正確
    {
        z=1;
        for(int i=0;i<30;i++)//用f數組來記錄組合的順序(因爲d數組的記錄會在之後的深搜中被打亂)
        {
            f[i]=d[i];
        }
        ans=k;
    }
    dfs(t+1,u+1);//加1繼續
    for(int i=0;i<n;i++)//不要當前食物營養,繼續
    {
        c[i]-=b[t][i];
    }
    dfs(t+1,u);
}
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>a[i];
    }
    cin>>m;
    for(int i=0;i<m;i++)
    {
        for(int j=0;j<n;j++)
        {
            cin>>b[i][j];
        }
    }
    for(int i=1;i<=m;i++)
    {
        memset(c,0,sizeof(c));//每次都要清空c數組,c數組是用來存放總量,避免上次影響
        k=i;
        dfs(0,0);
    }
    cout<<ans<<" ";
    for(int i=0;i<ans;i++)//輸出答案,最後一個數據後不能帶有空格
     {
        if(i!=0)
        {
            cout<<" ";
        }
        cout<<f[i]+1;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章