题意:给出n,m,b分别代表这货的朋友数,题目数和单个monitor的花费;
下来有2*n行,分别是做题要花的钱,monitor的个数还有朋友们能解决问题的个数;
再下来是能解决问题的编号;然你做完这些题这货所需要的最少的钱。
思路:显然,对monitor个数由小到大排序,因为前面需要的monitor比较少,如果能解决完问题的话花钱比较少,由少到多递推,注意m<=20,所以可以用二进制表示集合,第一次正是写状压dp。各种错误。注意集合i可以用1<<i表示,还有就是移位运算符优先级比较低,多用括号,|对应集合的并;
用dp[i]表示解决i个问题需要的最少的钱数即可。
用dp[i]表示解决i个问题需要的最少的钱数即可。
/****************************
* author:crazy_石头
* date:2014/04/21
* time:124 ms
* algorithm:状压dp
* Pro:CF 417 D
***************************/
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std; #define INF 1LL<<60 #define eps 1e-8 #define A system("pause") #define rep(i,h,n) for(int i=(h);i<=(n);i++) #define ms(a,b) memset((a),(b),sizeof(a)) const int maxn=20; const int maxm=150; __int64 dp[(1<
>n>>m>>b; rep(i,0,n-1) { cin>>d[i].price>>d[i].monitor>>c; d[i].pro_num=0; rep(j,0,c-1) { int x; cin>>x; d[i].pro_num|=(1<<(x-1));//转化为集合存储; } } sort(d,d+n,cmp);//按显示器数量排序; rep(i,0,(1<