Input
The input has several test cases, each starts with n (2 <= n <= 16), the number of programs. The following n lines contain the name of the program and its priority, with each program on a line. The name is a string of no more than 10 characters. The priority is an integer from 1 to 100. The next line contains a single integer m (0 <= m <= 1,024), which is the length of the list of the conflicting programs. The following m lines each contains several names of the programs which cannot run together.
The input is terminated with a case n = 0. This case should not be processed.
Output
Print the case number and the maximal total priority value you can get on a line. Adhere to the sample output format.
Sample Input
3 HARDDISK 20 FLOPPY 10 CDROM 15 1 CDROM HARDDISK 5 HARDDISK 20 FLOPPY 10 CDROM 15 SERIAL 25 MOUSE 20 3 CDROM HARDDISK FLOPPY FLOPPY SERIAL SERIAL MOUSE 0
Sample Output
System 1: 30 System 2: 60
题意:先给出n个任务和每个任务的价值,然后给出m个限制条件,每个限制条件包括一些任务,说明这些任务不能同时进行处理。求能同时处理的任务的最大价值是多少。
分析:因为n不大于16,而且限制条件也比较少,所以很容易想到状态压缩。
先把那些限制条件转化为一个10进制整数,它的二进制形式中的1表示这些任务不能同时处理;然后从0开始枚举状态,判断当前状态与限制条件是否冲突,如果不冲突,算出当前状态的价值总和,与最大值进行比较即可。
注意:任务的名称不一定全是字母,可能由其他字符组成,我就是因为这里WA了还找不到错误。
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<cstdlib> #include<stack> #include<queue> #include<vector> #include<set> #include<map> #include<algorithm> using namespace std; typedef long long LL; map<string, int> mp; vector<int> v[1030]; int a[30]; int sta[1030]; int pro[17] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536}; int main() { int n, m, i, j, cas = 0; string str, tmp; int val; while(cin >> n && n) { mp.clear(); for(i = 1; i <= n; i++) { cin >> str >> val; mp[str] = i; a[i] = val; } memset(v, 0, sizeof(v)); memset(sta, 0, sizeof(sta)); cin >> m; getchar(); for(int k = 0; k < m; k++) { getline(cin, str); int len = str.length(); tmp = ""; for(i = 0; i < len; i++) { if(str[i] != ' ' && str[i] != '\0') //注意此处的判断条件 tmp += str[i]; else { v[k].push_back(mp[tmp]); tmp = ""; } } v[k].push_back(mp[tmp]); sort(v[k].begin(), v[k].end()); for(int j = 0; j < v[k].size(); j++) sta[k] += pro[n-v[k][j]]; } int maxn = 1; for(i = 1; i <= n; i++) maxn *= 2; int ans = 0; for(int i = 0; i < maxn; i++) { int flag = 1; for(j = 0; j < m; j++) { if((i & sta[j]) == sta[j]) { flag = 0; break; } } if(flag) { int tmp_sum = 0; int tt = 0, temp = i; while(temp) { if(temp % 2 == 1) tmp_sum += a[n-tt]; tt++; temp /= 2; } ans = max(ans, tmp_sum); } } printf("System %d: %d\n", ++cas, ans); } return 0; }