2 3 Computer 3 3 English 20 1 Math 3 2 3 Computer 3 3 English 6 3 Math 6 3
2 Computer Math English 3 Computer English MathHintIn the second test case, both Computer->English->Math and Computer->Math->English leads to reduce 3 points, but the word "English" appears earlier than the word "Math", so we choose the first order. That is so-called alphabet order.
这里使用搜索+剪枝
#include <iostream> #include <string> #include <string.h> #include <algorithm> using namespace std; const int MAXN = 32868; int pow[17] = {1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384}; int hash[MAXN]; int temp[20]; //临时解决方案 bool used[20]; // int path[20]; int ans,i,j,t,n; typedef struct Node{ int cost,dead; char name[300]; }Node; Node arr[20]; //穷举法 + 剪枝 void dfs(int index, int cnt,int sum,int cur,int state){ if(cnt == n){ if(sum < ans){ ans = sum; for(int i=0; i<n; i++){ path[i] = temp[i]; } return; } } //剪枝. 如当前的结果比以前算出的结果大,就直接返回 if(hash[state] != -1 && sum > hash[state]) return; if(hash[state] == -1 || hash[state] > sum){ hash[state] = sum; } for(int k=0; k<n; k++){ if(!used[k]){ int tempCur,tempSum; if(cur + arr[k].cost > arr[k].dead){ tempSum = sum + cur + arr[k].cost - arr[k].dead; }else{ tempSum = sum; } tempCur = cur + arr[k].cost; used[k] = true; temp[cnt] = k; //记录 dfs(k, cnt+1, tempSum, tempCur, state + pow[k] ); used[k] = false; } } } int main(){ freopen("in.txt","r",stdin); cin >> t; while(t--){ cin >> n; for(i=0; i<n; i++){ scanf("%s %d %d", arr[i].name, &arr[i].dead, &arr[i].cost); } memset(hash,-1,sizeof(hash)); memset(used,false,sizeof(used)); ans = 0x3fffffff; dfs(-1,0,0,0,0); cout << ans << endl; for(i=0; i<n; i++){ printf("%s\n",arr[ path[i] ].name); } } return 0; }