hihocoder-1486物品价值(状压dp)

题目链接:

物品价值

小Hi现在有n个物品,每个物品都有一个价值。并且这n个物品总共有m个不同的属性,每个物品都具有其中若干属性。

小Ho要从中选出若干物品,满足每个属性都正好有奇数个物品拥有,且被选出的物品价值总和最大。你能帮助小Ho完成任务么?

Input

第一行一个数T(<=10),表示数据组数。对于每一组数据:

第一行两个数n,m(1<=n<=1000,m<=10)

接下来每两行描述一件物品。对于每一件物品:

第一行两个数v和s,表示其价值和所含属性数量(v<=100000,s<=m)

第二行s个数,表示该物品拥有的属性编号(1<=编号<=m)

Output

物品价值总和的最大值。

Sample Input

1
3 2
2 1
1
2 1
2
5 2
1 2

Sample Output

5

题意:

思路:m<=10,所以可以用二进制表示奇数个还是偶数个,然后就可以转移了

代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
int n,m,v[1010],a[1010];
int dp[1010][1026];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            int w,x,tep=0;
            scanf("%d%d",&v[i],&w);
            for(int j=1;j<=w;j++)
            {
                scanf("%d",&x);
                x--;
                tep+=(1<<x);
            }
            a[i]=tep;
        }
        memset(dp,-1,sizeof(dp));
        dp[0][0]=0;
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<(1<<m);j++)dp[i][j]=dp[i-1][j];
            for(int j=0;j<(1<<m);j++)
            {
                if(dp[i-1][j]>=0)dp[i][j^a[i]]=max(dp[i][j^a[i]],dp[i-1][j]+v[i]);
            }
        }
        cout<<dp[n][(1<<m)-1]<<endl;
    }
    return 0;
}

  

时间: 2024-11-12 16:54:19

hihocoder-1486物品价值(状压dp)的相关文章

hihocoder #1486 : 物品价值

dp[i][j]  到第i个物品 状态为 j 的二进制串 能得到的最大价值 #include<cstdio> #include<cstring> #include<map> #include<iostream> #include<algorithm> #include<math.h> #include<map> #include<queue> #include<set> #include<ve

最小总代价 状压DP

描述 n个人在做传递物品的游戏,编号为1-n. 游戏规则是这样的:开始时物品可以在任意一人手上,他可把物品传递给其他人中的任意一位:下一个人可以传递给未接过物品的任意一人. 即物品只能经过同一个人一次,而且每次传递过程都有一个代价:不同的人传给不同的人的代价值之间没有联系:求当物品经过所有n个人后,整个过程的总代价是多少. 格式 输入格式 第一行为n,表示共有n个人(16>=n>=2):以下为n*n的矩阵,第i+1行.第j列表示物品从编号为i的人传递到编号为j的人所花费的代价,特别的有第i+1

[转]状态压缩dp(状压dp)

状态压缩动态规划(简称状压dp)是另一类非常典型的动态规划,通常使用在NP问题的小规模求解中,虽然是指数级别的复杂度,但速度比搜索快,其思想非常值得借鉴. 为了更好的理解状压dp,首先介绍位运算相关的知识. 1.'&'符号,x&y,会将两个十进制数在二进制下进行与运算,然后返回其十进制下的值.例如3(11)&2(10)=2(10). 2.'|'符号,x|y,会将两个十进制数在二进制下进行或运算,然后返回其十进制下的值.例如3(11)|2(10)=3(11). 3.'^'符号,x^y

状压DP题集

[状压DP]Codeforces - 580D Kefa and Dishes (状压DP+记忆化搜索)(经典) 题目大意: 有$n ( n \leq18 )$个菜,现在要挑选$m$道菜,每个菜有一个满意度$a_i$,还有$k$个关系,每个关系为 $a b c$,表示$a$在$b$之前吃的话,就会额外增加$c$的满意度,现在要你输出最大的满意度. 解题分析:$n$的数据范围很小,很容易想到状压DP. #include <bits/stdc++.h> using namespace std; #

NOJ 1116 哈罗哈的大披萨 【淡蓝】 [状压dp+各种优化]

我只能说,珍爱生命,远离卡常数的题...感谢陈老师和蔡神,没有他们,,,我调一个星期都弄不出来,,,, 哈罗哈的大披萨 [淡蓝] 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 73            测试通过 : 9 描述 热风哈罗哈(三牌楼)店正在搞活动:他们将提供一个大披萨给第一个告诉他们以下信息的人:一次购买任一种披萨,哪种单位面积的价格最低.问题初步想一想,好像是这么解决:“对于每个披萨计算平均

状压DP uvalive 6560

1 // 状压DP uvalive 6560 2 // 题意:相邻格子之间可以合并,合并后的格子的值是之前两个格子的乘积,没有合并的为0,求最大价值 3 // 思路: 4 // dp[i][j]:第i行j状态下的值 5 // j:0表示不合并,1表示向下合并 6 // 一开始输入要修改一下,然后滚动数组优化 7 8 #include <iostream> 9 #include <algorithm> 10 #include <cstring> 11 #include &

UVA 1252 Twenty Questions 状压DP

简单状压DP: 当前状态s如果这个物品有状态a个属性,枚举下一个要猜测的特征k dp[s][a]=min(dp[s][a],max(dp[s+k][a],dp[s+k][a+k])+1); 4643 - Twenty Questions Asia - Tokyo - 2009/2010 Consider a closed world and a set of features that are defined for all the objects in the world. Each feat

ZOJ3471 MostPowerful 状压DP

同类类于poj3311,但是要简单,不用转什么弯子 直接  十种气体  每种是否存在的状态  s,然后 dp[s]  = max(dp[s],dp[s - {被碰的气体状态}] + 两气体相碰获得的价值);想起来不难,写起来也算比较简单 int n; int dp[1<<12]; int mp[10 + 5][10 + 5]; void init() { memset(mp,0,sizeof(mp)); memset(dp,0,sizeof(dp)); } bool input() { whi

【状压dp】Most Powerful

[ZOJ3471]Most Powerful Time Limit: 2 Seconds      Memory Limit: 65536 KB Recently, researchers on Mars have discovered N powerful atoms. All of them are different. These atoms have some properties. When two of these atoms collide, one of them disappe