Farmer John prides himself on having the healthiest dairy cows in the world. He knows the vitamin content for one scoop of each feed type and the minimum daily vitamin requirement for the cows. Help Farmer John feed his cows so they stay healthy while minimizing the number of scoops that a cow is fed.
Given the daily requirements of each kind of vitamin that a cow needs, identify the smallest combination of scoops of feed a cow can be fed in order to meet at least the minimum vitamin requirements.
Vitamins are measured in integer units. Cows can be fed at most one scoop of any feed type. It is guaranteed that a solution exists for all contest input data.
Line 1: | integer V (1 <= V <= 25), the number of types of vitamins |
Line 2: | V integers (1 <= each one <= 1000), the minimum requirement for each of the V vitamins that a cow requires each day |
Line 3: | integer G (1 <= G <= 15), the number of types of feeds available |
Lines 4..G+3: | V integers (0 <= each one <= 1000), the amount of each vitamin that one scoop of this feed contains. The first line of these G lines describes feed #1; the second line describes feed #2; and so on. |
4 100 200 300 400 3 50 50 50 50 200 300 200 300 900 150 389 399
The output is a single line of output that contains:
If more than one set of feedtypes yield a minimum of scoops, choose the set with the smallest feedtype numbers.
2 1 3
题目大意:就是说给奶牛喂食物,奶牛需要V种维生素每天,给出你每种维生素需要的量,有G种食物,给出你每种食物一勺含有每种维生素的量,同种食物每天最多喂一勺,问你想满足奶牛营养需求每天最少喂多少勺食物。输出勺数和哪几种食物(多组答案的时候输出字典序最小的)。
思路:明显的搜索呀,枚举没种食物喂或者不喂,我想如果找到答案后面的搜索就可以省略,于是用的迭代加深搜索(就是枚举勺数进行搜索)。第一次没加可行性剪纸只过了七组,第二次加上只过了九组还是T了(第八组耗时0.55sec),代码如下
1 /* 2 ID:fffgrdc1 3 PROB:holstein 4 LANG:C++ 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #include<cstring> 9 #include<cstdlib> 10 using namespace std; 11 int n,m; 12 int vis[20]={0}; 13 int temp[30]; 14 int aim[30]; 15 int a[20][30]; 16 void check(int ans) 17 { 18 memset(temp,0,sizeof(temp)); 19 for(int i=1;i<=n;i++) 20 { 21 if(vis[i]) 22 { 23 for(int j=1;j<=m;j++) 24 { 25 temp[j]+=a[i][j]; 26 } 27 } 28 } 29 /* 30 for(int i=1;i<=m;i++) 31 { 32 printf("%d ",temp[i]); 33 }printf("\n"); 34 */ 35 for(int i=1;i<=m;i++) 36 { 37 if(temp[i]<aim[i])return ; 38 } 39 printf("%d",ans); 40 for(int i=1;i<=n;i++) 41 if(vis[i])printf(" %d",i);printf("\n"); 42 exit(0); 43 } 44 void dfs(int x,int maxn) 45 { 46 if(x==maxn) 47 { 48 check(maxn); 49 return ; 50 } 51 for(int i=1;i<=n;i++) 52 { 53 if(n-i+1<maxn-x)return; 54 if(!vis[i])vis[i]=1,dfs(x+1,maxn),vis[i]=0; 55 } 56 } 57 int main() 58 { 59 freopen("holstein.in","r",stdin); 60 freopen("holstein.out","w",stdout); 61 scanf("%d",&m); 62 for(int i=1;i<=m;i++) 63 { 64 scanf("%d",&aim[i]); 65 } 66 scanf("%d",&n); 67 for(int i=1;i<=n;i++) 68 { 69 for(int j=1;j<=m;j++) 70 { 71 scanf("%d",&a[i][j]); 72 } 73 } 74 for(int i=1;i<=n;i++) 75 { 76 dfs(0,i); 77 } 78 return 0; 79 }
想了想,作为普适算法,每个点都得过,总会经历最坏情况的,于是打算直接写最裸最暴力的枚举,也就是枚举每种食物的状态,喂或者不喂。再加上最优化剪枝,代码如下
1 /* 2 ID:fffgrdc1 3 PROB:holstein 4 LANG:C++ 5 */ 6 #include<cstdio> 7 #include<iostream> 8 #include<cstring> 9 #include<cstdlib> 10 using namespace std; 11 int n,m; 12 int vis[20]={0}; 13 int temp[30]; 14 int aim[30]; 15 int a[20][30]; 16 int ansn=30,nown=0,ans[30]; 17 void check() 18 { 19 memset(temp,0,sizeof(temp)); 20 for(int i=1;i<=n;i++) 21 { 22 if(vis[i]) 23 { 24 for(int j=1;j<=m;j++) 25 { 26 temp[j]+=a[i][j]; 27 } 28 } 29 } 30 for(int i=1;i<=m;i++) 31 { 32 if(temp[i]<aim[i])return ; 33 } 34 ansn=nown; 35 int tempcnt=0; 36 for(int i=1;i<=n;i++) 37 if(vis[i]) 38 ans[++tempcnt]=i; 39 return ; 40 } 41 void dfs(int x) 42 { 43 //printf("%d\n",x); 44 if(x==n) 45 { 46 check(); 47 return; 48 } 49 vis[x+1]=1;nown++; 50 if(nown<ansn) 51 dfs(x+1); 52 vis[x+1]=0;nown--; 53 dfs(x+1); 54 } 55 int main() 56 { 57 freopen("holstein.in","r",stdin); 58 freopen("holstein.out","w",stdout); 59 scanf("%d",&m); 60 for(int i=1;i<=m;i++) 61 { 62 scanf("%d",&aim[i]); 63 } 64 scanf("%d",&n); 65 for(int i=1;i<=n;i++) 66 { 67 for(int j=1;j<=m;j++) 68 { 69 scanf("%d",&a[i][j]); 70 } 71 } 72 dfs(0); 73 printf("%d",ansn); 74 for(int i=1;i<=ansn;i++) 75 printf(" %d",ans[i]); 76 printf("\n"); 77 return 0; 78 }
果然秒过(极限数据0.011sec,第八组0.00sec)。。。。可能是我迭代加深写丑了。。。。再改改