hdu 4778 Gems Fight! 状压dp

本文介绍了一道HDU4778竞赛题的解题思路,通过状态压缩动态规划(状压DP)的方法来解决两人博弈问题。具体地,题目涉及根据给定的颜色宝石数量和合成规则,计算先手与后手获得魔法石差值的最大化。文章详细解释了状态转移方程,并提供了完整的C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自wdd :http://blog.youkuaiyun.com/u010535824/article/details/38540835

题目链接:hdu 4778

 

状压DP

         用DP[i]表示从i状态选到结束得到的最大值

 

代码也来自wdd

 1 /******************************************************
 2  * File Name:   b.cpp
 3  * Author:      kojimai
 4  * Creater Time:2014年08月13日 星期三 11时42分53秒
 5 ******************************************************/
 6 /*
 7  *有g种颜色的宝石,在一个容器中每s个同色宝石可以合成一个魔法石,给你b个包,里面有一定数目的宝石。
 8  *两人博弈,每个人每个回合把一个包中的所有的宝石放进容器中,如果该操作能得到一个魔法石,则能再进行一次操作
 9  *两个人都采取最有策略,问最终先手得到的魔法石与后手得到的魔法石的差值为多少
10 
11  *状压DP,dp[i]表示i状态为起始,选到结束能得到的最大值
12  *i&(1<<j)==0 表示当前状态下j已经选过了
13  *i&(1<<j)==1 表示当前状态下j可选,转移方程:
14  **dp[i]=max(dp[i],dp[i^(1<<j)]+cnt) 在i^(1<<j)状态下选j能得到cnt个魔法石
15  **dp[i]=max(dp[i],-dp[i^(1<<j)])    选了j之后得不到魔法石
16 */
17 #include<cstdio>
18 #include<cstring>
19 #include<cmath>
20 #include<algorithm>
21 #include<iostream>
22 using namespace std;
23 #define FFF -23333333
24 int gem[22][9];//每个包中的宝石
25 int now[9];//当前状态每种宝石的数目
26 int dp[1<<21];//1表示还剩哪些位可以选,0表示该位已经选了,在该状态下一直选到结束的最大情况
27 int main()
28 {
29     int g,b,s;
30     while(cin>>g>>b>>s)//g-colornum b-bag s-least
31     {
32         if(g+b+s==0)
33             break;
34         memset(gem,0,sizeof(gem));
35         for(int i=0;i<b;i++)
36         {
37             int x,y;
38             scanf("%d",&x);
39             for(int j=0;j<x;j++)//读取每个包中的宝石数
40             {
41                 scanf("%d",&y);
42                 gem[i][y]++;
43             }
44         }
45         int all=(1<<b);
46         dp[0]=0;
47         for(int i=1;i<all;i++)
48         {
49             dp[i]=FFF;
50             memset(now,0,sizeof(now));
51             for(int j=0;j<b;j++)
52             {
53                 if((i&(1<<j))==0)//当前i状态中j不可选,即之前j已经选过了,统计出所有已经选过的点得到的当前剩余的宝石
54                 {
55                     for(int k=1;k<=g;k++)
56                     {
57                         now[k]=(now[k]+gem[j][k])%s;
58                     }
59                 }
60             }
61         /*    cout<<"i="<<i<<":"<<endl;
62             for(int j=1;j<=g;j++)
63                 cout<<now[j]<<' ';
64         */    int cnt=0;
65             for(int j=0;j<b;j++)
66             {
67                 if((i&(1<<j))!=0)
68                 {
69                     cnt=0;
70                     for(int k=1;k<=g;k++)
71                     {
72                         int t=now[k]+gem[j][k];
73                         cnt+=t/s;
74                     }
75                     //cout<<"j="<<j<<"  cnt="<<cnt<<endl;
76                     if(cnt)
77                         dp[i]=max(dp[i],cnt+dp[i^(1<<j)]);
78                     else
79                         dp[i]=max(dp[i],-dp[i^(1<<j)]);
80                 }
81             }
82             //cout<<"i="<<i<<" dp="<<dp[i]<<endl;
83         }
84         cout<<dp[all-1]<<endl;
85     }
86     return 0;
87 }

 

转载于:https://www.cnblogs.com/njczy2010/p/3935650.html

资源下载链接为: https://pan.quark.cn/s/22ca96b7bd39 在当今的软件开发领域,自动化构建与发布是提升开发效率和项目质量的关键环节。Jenkins Pipeline作为一种强大的自动化工具,能够有效助力Java项目的快速构建、测试及部署。本文将详细介绍如何利用Jenkins Pipeline实现Java项目的自动化构建与发布。 Jenkins Pipeline简介 Jenkins Pipeline是运行在Jenkins上的一套工作流框架,它将原本分散在单个或多个节点上独立运行的任务串联起来,实现复杂流程的编排与可视化。它是Jenkins 2.X的核心特性之一,推动了Jenkins从持续集成(CI)向持续交付(CD)及DevOps的转变。 创建Pipeline项目 要使用Jenkins Pipeline自动化构建发布Java项目,首先需要创建Pipeline项目。具体步骤如下: 登录Jenkins,点击“新建项”,选择“Pipeline”。 输入项目名称和描述,点击“确定”。 在Pipeline脚本中定义项目字典、发版脚本和预发布脚本。 编写Pipeline脚本 Pipeline脚本是Jenkins Pipeline的核心,用于定义自动化构建和发布的流程。以下是一个简单的Pipeline脚本示例: 在上述脚本中,定义了四个阶段:Checkout、Build、Push package和Deploy/Rollback。每个阶段都可以根据实际需求进行配置和调整。 通过Jenkins Pipeline自动化构建发布Java项目,可以显著提升开发效率和项目质量。借助Pipeline,我们能够轻松实现自动化构建、测试和部署,从而提高项目的整体质量和可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值