Codeforces 744C. Hongcow Buys a Deck of Cards(状压DP)
2024-10-21 03:04:37
这题的难点在于状态的设计
首先显然是个状压,需要一维表示卡的状态,另一维如果设计成天数,难以知道当前的钱数,没法确定是否能够购买新的卡,如果设计成钱数,会发现状态数过多,空间与时间都无法承受。但是可以发现,如果没有买卡的钱会因当前卡数变化而变化这个条件的话,买卡的钱是一定的,而我们因拥有卡而省的钱不会超过120(1+2+3+...+15)。所以可以将状态设计成f[i][j]表示卡的状态为i,省了j个红币,能省多少个蓝币。
然后就结束了...
注意所有下标为状态的数组的大小T T...
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
using namespace std;
const int maxn=, inf=1e9;
int n, st, sumr, sumb, ans;
int r[maxn], b[maxn], cntr[<<], cntb[<<], f[<<][];
char ch[maxn][];
inline void read(int &k)
{
int f=; k=; char c=getchar();
while(c<'' || c>'') c=='-'&&(f=-), c=getchar();
while(c<='' && c>='') k=k*+c-'', c=getchar();
k*=f;
}
int main()
{
read(n); st=(<<n)-;
for(int i=;i<=n;i++)scanf("%s", ch[i]), read(r[i]), read(b[i]), sumr+=r[i], sumb+=b[i];
for(int i=;i<=st;i++)
for(int j=;j<=n;j++)
if(i&(<<(j-)))
cntr[i]+=(ch[j][]=='R')?:, cntb[i]+=(ch[j][]=='B')?:;
memset(f,-,sizeof(f)); f[][]=;
for(int i=;i<=st;i++)
for(int j=;j<=;j++)
if(f[i][j]!=-)
for(int k=;k<=n;k++)
if(!(i&(<<(k-))))
{
int numr=min(r[k], cntr[i]), numb=min(b[k], cntb[i]);
f[i|(<<(k-))][j+numr]=max(f[i|(<<(k-))][j+numr], f[i][j]+numb);
}
ans=inf;
for(int i=;i<=;i++)
if(f[st][i]!=-)
ans=min(ans, max(sumr-i, sumb-f[st][i]));
printf("%d\n", ans+n);
}
最新文章
- C# 读取app.config配置文件 节点键值,提示 ";配置系统未能初始化"; 错误的解决方案
- Lintcode 85. 在二叉查找树中插入节点
- CentOS7 编译安装 Nodejs (实测 笔记 Centos 7.0 + node 0.10.33)
- STL之序列式容器list与forward_list
- C# IntPtr转换为Byte[]
- Java Web开发Tomcat中三种部署项目的方法
- IT编程培训,线上线下,孰优孰劣
- linux下用mail发送邮件
- 11-C语言指针
- mysql 删除重复数据sql声明
- C++ 头文件系列(ios)
- OpenCV探索之路(九):模板匹配
- (转)java匿名内部类详解
- HDU 1728 逃离迷宫(DFS经典题,比赛手残写废题)
- dubbo服务运行的三种方式
- appium python中的android uiautomator定位
- cpp #,##
- springcloud第一步:创建eureka注册服务
- js-input框中写入的小写小写字母全部转换成大写字母的js代码
- c++中的c_str()用法