HDU 4778 记忆化搜索&状压

给出G种宝石,B个包,和S,S代表到时候每种颜色的宝石凑齐S个能变成一个魔法石

每个包里有N种宝石,分别为c1,c2.......

然后两人轮流拿包,每个包只能拿一次,拿出包把宝石放地上。

如果能变成魔法石则拿走魔法石,下一次还这个人拿包,没变成则换人。

魔法石的个数就是获得分数,问两人最优的时候分差是多少。

状压记忆化搜索

一共21个包,状压存当前取包的状态

无论怎样取,最后获得的魔法石数量一定

dp[i]表示在i状态下,先手可以获得的最高分数

#include "stdio.h"
#include "string.h"

int aim,g,b,s;
int dp[1<<22],c[25][10];
int bit[25];
int inf=0x3f3f3f3f;

int Max(int a,int b)
{
    if (a<b)return b;
    else return a;
}
int dfs(int cur,int sum,int temp[])
{
    int ans,i,next,j,w,cnt;
    int mark[10];
    if (cur==aim || sum==0) return 0;
    if (dp[cur]!=inf) return dp[cur];

    ans=0;
    for (i=1;i<=b;i++)
        if (cur&bit[i])
        {
            next=cur^bit[i];
            cnt=0;
            for (j=1;j<=g;j++)
            {
                mark[j]=temp[j]+c[i][j];
                cnt+=mark[j]/s;
                mark[j]%=s;
            }
            if (cnt>0) w=cnt+dfs(next,sum-cnt,mark);
            else w=sum-dfs(next,sum,mark);
            ans=Max(ans,w);
        }
    return dp[cur]=ans;
}
int main()
{
    int i,n,x,sum,aim,ans;
    int all[10],mark[25];
    bit[1]=1;
    for (i=2;i<=22;i++)
        bit[i]=bit[i-1]*2;

    while (scanf("%d%d%d",&g,&b,&s)!=EOF)
    {
        if (g+b+s==0) break;
        memset(c,0,sizeof(c));
        memset(all,0,sizeof(all));
        for (i=1;i<=b;i++)
        {
            scanf("%d",&n);
            while (n--)
            {
                scanf("%d",&x);
                c[i][x]++;
                all[x]++;
            }
        }
        sum=0;
        for (i=1;i<=g;i++)
            sum+=all[i]/s;

        aim=bit[b+1]-1;
        memset(mark,0,sizeof(mark));
        memset(dp,inf,sizeof(dp));
        ans=dfs(0,0,mark);
        printf("%d\n",ans-(sum-ans));
    }
    return 0;
}
时间: 2024-10-15 04:58:18

HDU 4778 记忆化搜索&状压的相关文章

URAL 1152. False Mirrors (记忆化搜索 状压DP)

题目链接 题意 : 每一颗子弹破坏了三个邻近的阳台.(第N个阳台是与第1个相邻)射击后后的生存的怪物都对主角造成伤害- 如此,直到所有的怪物被消灭,求怎样射击才能受到最少伤害. 思路 : 状压,数据不是很大,可以爆一爆,或者DFS下去就行,枚举每一种状态. 1 //1152 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #define oo 1 << 28 6 using n

HDU 1078 记忆化搜索

FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4575 Accepted Submission(s): 1829 Problem Description FatMouse has stored some cheese in a city. The city can be considered as a

hdu 4960 记忆化搜索 DP

Another OCD Patient Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 490    Accepted Submission(s): 180 Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) patient. This morni

hdu 3644 记忆化搜索

题目:给出一个有向图,从1到n,每个结点有个权值,每走一步,分值为结点权值的LCM,而且每一步的LCM都要有变化,问到达N的时候分值恰好为K的路径有多少条 记忆化搜索,虽然做过很多了,但是一直比较慢,这次总结出几点 1.注意确定终点状态 2.状态的初始化 3.不可能状态的排除 代码是参考cxlove写的,kuangbin博客要是刷完了,下一个就刷他啦 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm>

hdu 1978 记忆化搜索

How many ways Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5203    Accepted Submission(s): 3067 Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下:1.机器人一开始在棋盘的起始点并有起

hdu 1208 记忆化搜索

题目大意:只能按照格子上的数字*方向走,从左上走到右下Sample Input42331121312313110Sample Output3 直接记忆化搜索,注意是0的情况 1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<cmath> 6 #include<queue> 7 #include<

hdu 1514 记忆化搜索

题意是给4堆(堆的高度小于等于40)有颜色(颜色的种类小于等于20)的物品,你有一个篮子最多能装5件物品,每次从这4堆物品里面任取一件物品放进篮子里,但是取每堆物品时,必须先取上面的物品,才能取下面的物品,如果发现篮子里的两种物品的颜色一样,那么把这两种物品拿出来,问最后最多能拿出多少对物品?:解题思路:记忆化搜索+dp+状态压缩:因为40×40×40×40不会太大,所以可以用dp[x[1]][x[2]][x[3]][x[4]]记录搜索的状态:dp[x[1]][x[2]][x[3]][x[4]]

FatMouse and Cheese (hdu 1078 记忆化搜索)

FatMouse and Cheese Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 5463    Accepted Submission(s): 2227 Problem Description FatMouse has stored some cheese in a city. The city can be considere

HDU 1978 记忆化搜索(dfs+dp)

Y - How many ways Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Practice HDU 1978 Appoint description: Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标有的能量. 2.机器