cdoj 1141 酱神寻宝 状压dp

酱神寻宝

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.uestc.edu.cn/#/problem/show/1141

Description



酱神来到了一座小岛,岛上有n个箱子。

一共有3中不同的钥匙,金钥匙、银钥匙和万能钥匙。酱神一开始有a把金钥匙、b把银钥匙和c把万能钥匙。

第i个箱子上有xi把金锁,yi把银锁。金钥匙只能打开金锁,银钥匙只能打开银锁,万能钥匙两种锁都能打开。用于打开锁的钥匙会立刻损坏,酱神会丢掉损坏的钥匙。箱子里有ai把金钥匙、bi把银钥匙和ci把万能钥匙,想要取出箱内的钥匙必须要打开这xi+yi把锁。

酱神的目的是使他拥有的钥匙总数最多。一旦酱神认为自己已经拥有了最多的钥匙,他就不会去开剩下的箱子了。


Input

第一行一个数n。

接下来有n行。每行5个数,xi,yi,ai,bi,ci。

最后一行3个数a,b,c。

1=
0=

Output

输出一个数酱神的最多钥匙数。

Sample Input

3
1 0 0 0 1
2 4 0 8 0
3 9 10 9 8
3 1 2

Sample Output

8

HINT

题意

 

 

题解:

状压dp,借用一个贪心的思想,每次能用A就用A,不能再用万能钥匙

啊,用的bfs实现的

代码:

//qscqesze
#include 
#include 
#include 
#include 
#include 
#include 
#include <set>
#include 
#include 
#include 
#include 
#include 
#include 
#include 
typedef long long ll;
using namespace std;
//freopen("D.in","r",stdin);
//freopen("D.out","w",stdout);
#define sspeed ios_base::sync_with_stdio(0);cin.tie(0)
#define test freopen("test.txt","r",stdin)  
#define maxn 2000001
#define mod 10007
#define eps 1e-9
int Num;
char CH[20];
const int inf=0x3f3f3f3f;
const ll infll = 0x3f3f3f3f3f3f3f3fLL;
inline ll read()
{
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
inline void P(int x)
{
    Num=0;if(!x){putchar('0');puts("");return;}
    while(x>0)CH[++Num]=x%10,x/=10;
    while(Num)putchar(CH[Num--]+48);
    puts("");
}
//**************************************************************************************
struct Box
{
    int a,b,c,d,e;
}box[20];

struct node
{
    int a,b;
};

int dp[1<<15][200];
int main()
{
    //test;
    int n=read();
    for(int i=0;i)
        box[i].a=read(),box[i].b=read(),box[i].c=read(),box[i].d=read(),box[i].e=read();
    int aa=read(),bb=read(),cc=read();
    memset(dp,-1,sizeof(dp));
    dp[0][aa]=cc;
    queueq;
    q.push((node){0,aa});
    int ans=0;
    while(!q.empty())
    {
        node now=q.front();
        q.pop();
        int all=aa+bb+cc;
        for(int i=0;i)
        {
            if(now.a>>i&1)
            {
                all+=box[i].c+box[i].d+box[i].e-box[i].a-box[i].b;
            }
        }
        ans=max(ans,all);
        int nowa=now.b,nowc=dp[now.a][now.b],nowb=all-nowa-nowc;
        //cout<
        for(int i=0;i)
        {
            if(!(now.a>>i&1))
            {
                if(nowa>=box[i].a)
                {
                    if(nowb>=box[i].b)
                    {
                        if(nowc+box[i].e>dp[now.a|(1<box[i].c])
                        {
                            dp[now.a|(1<box[i].e;
                            q.push((node){now.a|(1<box[i].c});
                        }                    
                    }
                    else if(nowc+nowb>=box[i].b)
                    {
                        if(nowc+box[i].e-box[i].b+nowb>dp[now.a|(1<box[i].c])
                        {
                            dp[now.a|(1<nowb;
                            q.push((node){now.a|(1<box[i].c});
                        }
                    }
                }
                else if(nowa+nowc>=box[i].a)
                {
                    int sp=nowc-box[i].a+nowa;
                    if(nowb>=box[i].b)
                    {
                        if(nowc+box[i].e-box[i].a+nowa>dp[now.a|(1<<i)][box[i].c])
                        {
                            dp[now.a|(1<nowa;
                            q.push((node){now.a|(1<<i),box[i].c});
                        }
                    }
                    else if(sp+nowb>=box[i].b)
                    {
                        if(sp+box[i].e-box[i].b+nowb>dp[now.a|(1<<i)][box[i].c])
                        {
                            dp[now.a|(1<nowb;
                            q.push((node){now.a|(1<<i),box[i].c});
                        }
                    }
                }
            }
        }
    }
    cout<endl;
}

 

你可能感兴趣的:(数据结构与算法)