曉萌作為乙個營養學專家,吃東西的時候總是要考慮是否能滿足他的各種營養物質需求,大家都說他是乙個有強迫症的吃貨。曉萌知道每種食品中營養物質的含量,請你幫他安排食譜,以保持他獲得所需營養物質的同時,吃的食品的種類最少。(營養物質含量為整數,每種食品曉萌只吃一次)。
輸入第1行為乙個整數v表示曉萌需要的營養物質的種類數(1≤v≤25)。
輸入第2行包括用空格分隔開的v個整數,依次表示每種營養物質的需求量(1≤每個整數≤1000)。
輸入第3行包括乙個整數g表示提供可以給曉萌吃的食品的種類數(1≤g≤15)。
接下來的g行,每行包括用空格分隔開的v個整數,g行中的第i行中v個整數依次表示第i種食品中每種營養物質的含量(1≤每個整數≤1000)。
輸出包括空格分隔的多個數,第乙個數為必需的最小的食品種數p;後面有p個數,表示所選擇的食品編號(按從小到大排列);如果有多個解,輸出食品序號最小的(即字典序最小)。
樣例輸入·
4
100 200 300 400
350 50 50 50
200 300 200 300
900 150 389 399
樣例輸出·
2 1 3
首先說一下思路吧
首要條件是 所吃食品種類越少越好,因此直接列舉食品種類為 1、2、3……g 的情況,以減少遍歷次數;
在前一思路之下,當前的關鍵點在於避免出現1、2、3、4 和 1、2、4、3 這樣的重複查詢(因為吃食品的次序不影響結果),否則會超時;即在遞迴過程中,若第 cur 種食品已經吃過後,只需要考慮序號在 cur 之後的食品
最後考慮字典序,因為尋找次序是從食品種類為 1 開始遞增,並且吃食品的順序是從序號小的食品開始,因此只要找到第乙個滿足條件的序列,必然是食品種類最少,並且字典序最小的序列。
附上**
#include
using
namespace
std;
struct food;
int v,g;
//用來標記吃過的食品
intmap[16]=;
//記錄需要的各種營養物質含量
int need[25];
//記錄當前吃過的食品各營養物質總量
int prov[25];
food food[16];
//標記是否已經找到滿足要求的食品
bool m;
//記錄當前食品種類
int kind;
//本層遞迴要吃第step種食品,前一層遞迴所吃食品序號為cur
void dfs(int step,int cur)
}if(m==true)
return;
//判斷本次遞迴是否吃夠 kind種食品
if(step>kind)
return;
//這裡要明白,在前一層遞迴,已經吃掉了序號為cur的食品
//因此,不需要再吃序號在cur之前的食品,否則會出現1、2、3、4和1、2、4、3這樣的重複序列
for(int i=cur;i<=g;i++)
int main()
cout
<1;
for(int i=1;i<=g;i++)
思路參考
在參考這篇部落格之前困於超時,參考了這篇部落格之後根據自己的理解終於通過了。
強迫症的吃貨
曉萌作為乙個營養學專家,吃東西的時候總是要考慮是否能滿足他的各種營養物質需求,大家都說他是乙個有強迫症的吃貨。曉萌知道每種食品中營養物質的含量,請你幫他安排食譜,以保持他獲得所需營養物質的同時,吃的食品的種類最少。營養物質含量為整數,每種食品曉萌只吃一次 輸入第1行為乙個整數v表示曉萌需要的營養物質...
強迫症的序列
小a是乙個中度強迫症患者,每次做陣列有關的題目都異常難受,他十分希望陣列的每乙個元素都一樣大,這樣子看起來才是最棒的,所以他決定通過一些操作把這個變成乙個看起來不難受的陣列,但他又想不要和之前的那個陣列偏差那麼大,所以他每次操作只給這個陣列的其中n 1個元素加1,但是小a並不能很好的算出最優的解決方...
強迫症的序列 牛客網 思維
輸入 第一行乙個整數t t 100 表示組數 對於每組資料有乙個n,表示序列的長度 0 n 100000 下面一行有n個數,表示每個序列的值 0 ai 1000 輸出 兩個數 第乙個數表示最小的操作步數 第二個數經過若干步以後的陣列元素是什麼 例如 1 31 2 3 輸出 3 4 這裡有乙個很奇怪的...