SRM588 Div1Medium KeyDungeonDiv1

来源:互联网 发布:vmware 12.5 mac os x 编辑:程序博客网 时间:2024/05/21 06:48

这题简直有毒,这么多奇奇怪怪的数组。。。
但这题确实很水
刚开始很明显的一个思路就是dp
定义dpsum,i,j,k表示当被开的门组成的二进制数为sum,
红色钥匙i把,绿色钥匙j,白色钥匙k把的情况是否存在
但是这样数组显然会炸
于是我们稍微仔细想想就会发现:
对于某一情况,知道白色钥匙数量,另外两种钥匙数量已经确定,
毕竟肯定是用完哪两种钥匙才会来用白色钥匙
我们可以定义dpsum,i表示当被开的门组成的二进制数为sum,白色钥匙k把时的红、绿钥匙数量
于是很容易就能dp
代码如下:

#include<bits/stdc++.h>using namespace std;#define M 12int a[M],b[M],c[M],d[M],e[M];struct node{    int x,y;}dp[1<<M][M*M];int main(){    int n,ans=0;    scanf("%d",&n);    for(int i=0;i<n;i++)scanf("%d",&a[i]);    for(int i=0;i<n;i++)scanf("%d",&b[i]);    for(int i=0;i<n;i++)scanf("%d",&c[i]);    for(int i=0;i<n;i++)scanf("%d",&d[i]);    for(int i=0;i<n;i++)scanf("%d",&e[i]);    int A,B,C;    scanf("%d %d %d",&A,&B,&C);    for(int sum=0;sum<(1<<n);sum++)        for(int k=0;k<M*M;k++)            dp[sum][k]=(node){-1,-1};    dp[0][C]=(node){A,B};    for(int sum=0;sum<(1<<n);sum++)        for(int k=0;k<M*M;k++){            if(dp[sum][k].x==-1&&dp[sum][k].y==-1)continue;            int i=dp[sum][k].x,j=dp[sum][k].y;            if(i+j+k>ans)ans=i+j+k;            for(int p=0;p<n;p++){                if(sum&(1<<p))continue;                if(i+k>=a[p]&&j+k>=b[p]&&i+j+k>=a[p]+b[p])                    dp[sum|(1<<p)][k-max(a[p]-i,0)-max(b[p]-j,0)+e[p]]=(node){max(0,i-a[p])+c[p],max(0,j-b[p])+d[p]};            }        }    printf("%d\n",ans);    return 0;}
1 1
原创粉丝点击