8.9 正睿暑期集训营 Day6
2018.8.9 正睿暑期集训营 Day6
时间:2.5h(实际)
期望得分:60+30+0
实际得分:40+30+0
为什么A就是40分。。这个咋就能150+ms过呢。。http://www.zhengruioi.com/submission/26647
A 萌新拆塔(状压DP)
如果杀掉的怪物和吃的宝石已知,那么状态也是可以直接算出来的(预处理),只需要求该状态的最大血量。
n很小,于是只需要2^n枚举已击杀的怪的状态,枚举下个怪转移DP最大血量?
因为有模仿怪,所以杀掉怪物后立即吃宝石不一定是最优的。
宝石只有在杀掉怪物后才能吃,即每个怪物有三种状态,3^n枚举就可以了。
已知状态可以算出清了哪些怪、还有哪些宝石没吃,但是可以直接用s1[s],s2[s]记录s状态清了哪些怪、吃了哪些宝石,可以直接在转移时更新(或是预处理,不过这么多次取模、除法会更慢?),枚举时也可以直接枚举里面的0(异或后lowbit枚举1)。
如果要吃某个宝石i,那么怪物i已经杀掉了,即状态s中i这一位已经是1(已经加过pw[i]),此时吃掉宝石变成2,直接再加pw[i]即可。
复杂度O(3^n*n)。
//3346ms 77996kb
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define lb(x) (x&-x)
#define gc() getchar()
typedef long long LL;
const int N=(1<<14)+5,M=5e6;
int pw[16],bit[N],ok[16],sap[N],sdp[N],smp[N],s1[M],s2[M];
LL f[M];
struct Monster
{
int H,A,D,S,ap,dp,mp,hp;
}A[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
LL Combat(Monster mon,LL hp,int atk,int def,int mdf)
{
if(mon.S&8) mon.A=atk, mon.D=def;
if(mon.S&2) def=0;
if(atk<=mon.D) return 0ll;
int dps=atk-mon.D, mon_dps=mon.A<=def?0:mon.A-def;
int tm=(mon.S&4)?2:1;
LL hpbef=hp; hp+=mdf;
if(mon.S&1) hp-=mon_dps*tm;
hp-=1ll*mon_dps*tm*((mon.H+dps-1)/dps-1);
return hp>hpbef?hpbef:hp;
}
int main()
{
pw[0]=1;
for(int i=1; i<=14; ++i) pw[i]=pw[i-1]*3;
for(int i=1; i<=14; ++i) bit[1<<i]=i;
for(int T=read(); T--; )
{
memset(ok,0,sizeof ok), memset(f,0,sizeof f);
int Hp=read(), Atk=read(), Def=read(), Mdf=read();
int n=read();
for(int i=0; i<n; ++i) A[i]=(Monster){read(),read(),read(),read(),read(),read(),read(),read()};
for(int K=read(); K--; ) ok[read()-1]|=1<<(read()-1);
int tot=(1<<n)-1;
for(int s=0; s<=tot; ++s)
{
sap[s]=Atk, sdp[s]=Def, smp[s]=Mdf;
for(int i=0; i<n; ++i) if(s>>i&1) sap[s]+=A[i].ap, sdp[s]+=A[i].dp, smp[s]+=A[i].mp;
}
int lim=pw[n]-1; f[0]=Hp;
for(int s=0; s<lim; ++s)
{
if(!f[s]) continue;//!
int S1=s1[s], S2=s2[s];
for(int i=S1^tot,j; i; i^=lb(i))
{
j=bit[lb(i)];
if((S1&ok[j])!=ok[j]) continue;
f[s+pw[j]]=std::max(f[s+pw[j]],Combat(A[j],f[s],sap[S2],sdp[S2],smp[S2]));
s1[s+pw[j]]=S1|(1<<j), s2[s+pw[j]]=S2;
}
for(int i=S1^S2,j; i; i^=lb(i))
{
j=bit[lb(i)];
f[s+pw[j]]=std::max(f[s+pw[j]],f[s]+A[j].hp);
s1[s+pw[j]]=S1, s2[s+pw[j]]=S2|(1<<j);
}
}
printf("%lld\n",f[lim]?f[lim]:-1ll);
}
return 0;
}
B 奇迹暖暖
C 风花雪月(DP)
见:https://www.cnblogs.com/SovietPower/p/9862098.html。
考试代码
A
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=17,M=205;
int n,lim,K,Atk,Def,Mdf,dgr[N],Enum,H[N],nxt[M],to[M];
LL Hp,Ans,mx[(1<<15)+2];
struct Monster
{
int H,A,D,S,ap,dp,mp,hp;
}A[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline void AddEdge(int v,int u){
++dgr[v], to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
}
inline bool Can(int x,int s)
{
for(int i=H[x]; i; i=nxt[i]) if(!((s>>to[i]-1)&1)) return 0;
return 1;
}
inline LL Kill(Monster mon,LL hp,int atk,int def,int mdf)
{
if(mon.S>>3&1) mon.A=atk, mon.D=def;
if(mon.S>>1&1) def=0;
if(atk<=mon.D) return 0ll;
int dps=atk-mon.D, mon_dps=mon.A<=def?0:mon.A-def;
int tm=(mon.S>>2&1)?2:1;
LL hpbef=hp; hp+=mdf;
if(mon.S&1) hp-=mon_dps*tm;
hp-=1ll*mon_dps*tm*((mon.H+dps-1)/dps-1);
return hp>hpbef?hpbef:hp;
}
void DFS(int s,LL hp,int atk,int def,int mdf)
{
if(mx[s]>=hp) return;
if(s==lim) {mx[s]=hp, Ans=std::max(Ans,hp); return;}
LL tmp=hp;
for(int i=0; i<n; ++i) if(!(s>>i&1)) tmp+=A[i+1].hp;
if(tmp<=mx[s]) return;
for(int i=n; i; --i)
if(!((s>>i-1)&1) && !dgr[i] && (tmp=Kill(A[i],hp,atk,def,mdf))>0)
{
for(int j=H[i]; j; j=nxt[j]) --dgr[to[j]];
DFS(s|(1<<i-1),tmp+A[i].hp,atk+A[i].ap,def+A[i].dp,mdf+A[i].mp);
for(int j=H[i]; j; j=nxt[j]) ++dgr[to[j]];
}
}
int main()
{
// freopen("A.in","r",stdin);
// freopen(".out","w",stdout);
for(int T=read(); T--; )
{
Ans=-1ll, Enum=1, memset(H,0,sizeof H), memset(mx,0,sizeof mx), memset(dgr,0,sizeof dgr);
Hp=read(), Atk=read(), Def=read(), Mdf=read();
n=read(), lim=(1<<n)-1;
for(int i=1; i<=n; ++i) A[i]=(Monster){read(),read(),read(),read(),read(),read(),read(),read()};
K=read();
for(int i=1; i<=K; ++i) AddEdge(read(),read());
DFS(0,Hp,Atk,Def,Mdf);
printf("%lld\n",Ans);
}
return 0;
}
B
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
typedef long long LL;
const int N=101;
int n,m,c;
LL Ans;
struct Event
{
int l,r,x,y;
}A[N];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
void DFS(int now,int rest,LL w)
{
if(!rest||now>n) {Ans=std::max(Ans,w); return;}
int X[6]; LL tmp;
for(int i=1; i<=m; ++i) X[i]=A[i].x;
DFS(now+1,rest,w);
for(int x=1; x<=rest; ++x)
{
tmp=0;
for(int i=1; i<=m; ++i)
if(A[i].l<=now&&A[i].r>=now&&A[i].x>0)
tmp+=std::min(A[i].x,x)*A[i].y, A[i].x-=x;
DFS(now+1,rest-x,w+tmp);
for(int i=1; i<=m; ++i) A[i].x=X[i];
}
}
void DFS2(int now,int rest,LL w)
{
if(!rest||now>n) {Ans=std::max(Ans,w); return;}
int X[N]; LL tmp;
for(int i=1; i<=m; ++i) X[i]=A[i].x;
DFS2(now+1,rest,w);
for(int x=1; x<=rest; ++x)
{
tmp=0;
for(int i=1; i<=m; ++i)
if(A[i].l<=now&&A[i].r>=now&&A[i].x>0)
tmp+=std::min(A[i].x,x)*A[i].y, A[i].x-=x;
DFS2(now+1,rest-x,w+tmp);
for(int i=1; i<=m; ++i) A[i].x=X[i];
}
}
int main()
{
// freopen("B2.in","r",stdin);
// freopen(".out","w",stdout);
n=read(), m=read(), c=read();
for(int i=1; i<=m; ++i) A[i]=(Event){read(),read(),read(),read()};
if(n<=5) DFS(1,c,0);
else DFS2(1,c,0);
printf("%lld\n",Ans);
return 0;
}
C
#include <cstdio>
#include <cctype>
#include <algorithm>
#define gc() getchar()
#define INF (1e6)
#define mod (1000000007)
typedef long long LL;
const int N=12;
int n,Sum,p[N],Q,c[N],have[N],Max,tot;
struct Fraction
{
LL x,y;
Fraction() {x=0, y=1;}
Fraction(LL x,LL y):x(x),y(y) {}
void Debug() {printf("%lld/%lld\n",x,y);}
LL Gcd(LL x,LL y) {return y?Gcd(y,x%y):x;}
inline void Fix() {LL g=Gcd(x,y); x/=g,y/=g;}
void Exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b) x=1, y=0;
else Exgcd(b,a%b,y,x), y-=a/b*x;
}
void Output()
{
if(y==1) {printf("%lld\n",x); return;}
LL inv,b;
Exgcd(y,mod,inv,b);
printf("%lld\n",inv*x%mod);
}
friend bool operator <(const Fraction &f,const Fraction &g)
{
return f.x*g.y<g.x*f.y;
}
friend Fraction operator +(const Fraction &f,int num)
{
Fraction res=Fraction(f.x+f.y*num,f.y);
res.Fix();
return res;
}
friend Fraction operator +(const Fraction &f,const Fraction &g)
{
Fraction res=Fraction(f.x*g.y+g.x*f.y,f.y*g.y);
res.Fix();
return res;
}
friend Fraction operator *(const Fraction &f,int num)
{
Fraction res=Fraction(f.x*num,f.y);
res.Fix();
return res;
}
friend Fraction operator *(const Fraction &f,const Fraction &g)
{
Fraction res=Fraction(f.x*g.x,f.y*g.y);
res.Fix();
return res;
}
}Ans,f[1000003];
inline int read()
{
int now=0;register char c=gc();
for(;!isdigit(c);c=gc());
for(;isdigit(c);now=now*10+c-'0',c=gc());
return now;
}
inline LL FP(LL x,int k)
{
LL t=1;
for(; k; k>>=1, x=x*x%mod)
if(k&1) t=t*x%mod;
return t;
}
bool Check(int now,Fraction res)
{
int rest=0;
for(int i=1; i<=n; ++i)
if(have[i]>=c[i]) rest+=have[i]-c[i];
for(int i=1; i<=n; ++i)
if(have[i]<c[i])
if(rest>=4*(c[i]-have[i])) rest-=(c[i]-have[i]<<2);
else return 0;
if(rest) return 1;
putchar('\n'); Ans.Debug();puts("+=");res.Debug();
printf("Number: "); for(int i=1; i<=n; ++i) printf("%d ",have[i]); putchar('\n');putchar('\n');
Ans=Ans+res, ++tot;
return 1;
}
void DFS(int now,Fraction res)
{
// printf("now:%d ",now), res.Debug();
if(Check(now,res)||now>n) return;
int mx=(Sum-c[now])*4+c[now];
// printf("mx:%d\n",mx);
Fraction tmp=Fraction(Q,p[now]);
for(int i=0; i<=mx; ++i)
have[now]=i, printf("%d Chose %d:",now,i), (tmp*i).Debug(), DFS(now+1,std::max(tmp*i,res)), have[now]=0;
}
int main()
{
freopen("C1.in","r",stdin);
// freopen(".out","w",stdout);
n=read();
for(int i=1; i<=n; ++i) Q+=(p[i]=read());
for(int i=1; i<=n; ++i) Sum+=(c[i]=read());
DFS(1,Fraction(0,1));
(Ans*Fraction(1,tot)).Output();
return 0;
}
8.9 正睿暑期集训营 Day6的更多相关文章
- 8.9 正睿暑期集训营 Day6 C 风花雪月(DP)
题目链接 完整比赛在这儿. 杜老师tql . 求期望要抽卡的次数,也就是求期望经历了多少不满足状态.而每个不满足的状态对答案的贡献为\(1\),所以可以直接算概率.即\(Ans=\sum_{不满足状态 ...
- 8.10 正睿暑期集训营 Day7
目录 2018.8.10 正睿暑期集训营 Day7 总结 A 花园(思路) B 归来(Tarjan 拓扑) C 机场(凸函数 点分治) 考试代码 A B C 2018.8.10 正睿暑期集训营 Day ...
- 8.6 正睿暑期集训营 Day3
目录 2018.8.6 正睿暑期集训营 Day3 A 亵渎(DP) B 绕口令(KMP) C 最远点(LCT) 考试代码 A B C 2018.8.6 正睿暑期集训营 Day3 时间:5h(实际) 期 ...
- 8.8 正睿暑期集训营 Day5
目录 2018.8.8 正睿暑期集训营 Day5 总结 A 友谊巨轮(线段树 动态开点) B 璀璨光滑 C 构解巨树 考试代码 A B C 2018.8.8 正睿暑期集训营 Day5 时间:3.5h( ...
- 8.7 正睿暑期集训营 Day4
目录 2018.8.7 正睿暑期集训营 Day4 A 世界杯(贪心) B 数组(线段树) C 淘汰赛 考试代码 A B C 2018.8.7 正睿暑期集训营 Day4 时间:5h(实际) 期望得分:. ...
- 8.5 正睿暑期集训营 Day2
目录 2018.8.5 正睿暑期集训营 Day2 总结 A.占领地区(前缀和) B.配对(组合) C 导数卷积(NTT) 考试代码 T1 T2 T3 2018.8.5 正睿暑期集训营 Day2 时间: ...
- 8.4 正睿暑期集训营 Day1
目录 2018.8.4 正睿暑期集训营 Day1 A 数对子 B 逆序对 C 盖房子 考试代码 A B C 2018.8.4 正睿暑期集训营 Day1 时间:4.5h(实际) 期望得分:30+50+3 ...
- 7.30 正睿暑期集训营 A班训练赛
目录 2018.7.30 正睿暑期集训营 A班训练赛 T1 A.蔡老板分果子(Hash) T2 B.蔡老板送外卖(并查集 最小生成树) T3 C.蔡老板学数学(DP NTT) 考试代码 T2 T3 2 ...
- 正睿OI集训游记
什么嘛....就是去被虐的... 反正就是难受就是了.各种神仙知识点,神仙题目,各式各样的仙人掌..... 但是还是学会了不少东西...... 应该是OI生涯最后一次集训了吧.... 这次的感言还是好 ...
随机推荐
- 关于swiper的tab(选项卡)中设置了autoHeight没有效果解决
autoHeight属性使用看官网的示例:https://www.swiper.com.cn/api/parameters/294.html swiper的选项卡结构查看:https://www.sw ...
- SSM数据库数据导出excel
首先,这是我对自己的需求而使用的逻辑,若有可以完美的地方方便告诉下小白. apache的poi MAVEN <dependency> <groupId>org.apache.p ...
- Bellman-Ford 最短路径算法
算法证明:http://courses.csail.mit.edu/6.006/spring11/lectures/lec15.pdf 先来看一个这样的图: 这是含有负边权的,如果是用djistra的 ...
- spring Mvc Web 编码相关 [model 到 视图传递数据] (九)
在某种编码环境,由bean注解的参数可能会发生乱码问题. 即可页面web.xml或其他地方都设备UTF-8, 但还是会有这样的问题. 首先不要使用model传到视图的数据. 第二,不要request. ...
- 雨林木风ghostwin7纯净版系统下载
雨林木风ghostwin7纯净版系统下载 关于easyuidatagrid的问题,跪求老司机带带我..... 关于cst_modesys/stat.h一个问题求解答谢谢 [程序]STM32使用SPI接 ...
- Export SQLite data to Excel in iOS programmatically(OC)
//For the app I have that did this, the SQLite data was fairly large. Therefore, I used a background ...
- bzoj 1432 数学(找规律)
我们可以发现所有的情况(除n=1时),都可以找到两个交叉的直线,就是第一层的那 两个线段所在的直线如图中左 那么我们以这个为准,两边对称着加直线,会得到右图,每一层是折线,且每 加一对儿就多两条线段, ...
- C - Segments POJ - 3304 (判断线段相交)
题目链接:https://vjudge.net/contest/276358#problem/C 题目大意:给你n条线段,问你是否存在一条线段使得所有的线段在这条直线的投影至少具有一个交点? 具体思路 ...
- 通俗理解决策树中的熵&条件熵&信息增益
参考通俗理解决策树算法中的信息增益 说到决策树就要知道如下概念: 熵:表示一个随机变量的复杂性或者不确定性. 假如双十一我要剁手买一件衣服,但是我一直犹豫着要不要买,我决定买这件事的不确定性(熵)为2 ...
- Linux 串口、usb转串口驱动分析(2-2) 【转】
转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=26807463&id=4186852 Linux 串口.usb转 ...