使用回溯,需要稍微剪枝,题目不难 #include<iostream> #include<fstream> #include<string> #include<memory.h> #include<cstdio> #include<cmath> #include<algorithm> #include<queue> #include<vector> using namespace std; ifstream fin("holstein.in"); ofstream fout("holstein.out"); int V,G; int request[26]; int feed[26][26]; int now_feed[26],rest_feed[26]; int max_res=999999999; int max_now; int res[26],now_res[26]; bool vis[26]; bool check(){ for(int i=0;i<V;i++){ if(now_feed[i]>0) return false; } return true; } void make(int x){ for(int i=0;i<V;i++){ now_feed[i]=now_feed[i]-feed[x][i]; } } void remake(int x){ for(int i=0;i<V;i++){ now_feed[i]=now_feed[i]+feed[x][i]; } } void move(int x){ for(int i=0;i<V;i++){ rest_feed[i]=rest_feed[i]-feed[x][i]; } } void remove(int x){ for(int i=0;i<V;i++){ rest_feed[i]=rest_feed[i]+feed[x][i]; } } bool bound(){ for(int i=0;i<V;i++){ if(rest_feed[i]<now_feed[i]) return false; } return true; } void solve(int dep){ if(max_now>=max_res) return ; if(check() && max_now<max_res){ max_res=max_now; for(int k=0;k<max_now;k++){ res[k]=now_res[k]; } } move(dep); now_res[max_now]=dep; max_now++; make(dep); solve(dep+1); remake(dep); max_now--; if(bound()) solve(dep+1); remove(dep); } int main(){ int i,j; fin>>V; for(i=0;i<V;i++){ fin>>request[i]; now_feed[i]=request[i]; } memset(rest_feed,0,sizeof(rest_feed)); fin>>G; for(i=0;i<G;i++){ for(j=0;j<V;j++){ fin>>feed[i][j]; rest_feed[j]+=feed[i][j]; } } memset(vis,false,sizeof(vis)); max_now=0; solve(0); fout<<max_res<<" "; for(i=0;i<max_res-1;i++){ fout<<res[i]+1<<" "; } fout<<res[max_res-1]+1<<endl; return 0; }