https://h5mota.com/tower/?name=zhrs2
#include<cstdio>
#include<map>
#include<thread>
#include<cstring>
using namespace std;
int siz=0;int pos0;int effects=11;
int pos[16][16]={};FILE* dbg;
int atk1=1,dex1=1,mdef1=10;//宝石增加能力
int hp1=75,hp2=200,hp3=200,hp4=400;
bool graph[33][33]={};
const int maxx=1<<24;
int *addhp;
/*
map<int,int >f;
map<int,int >pre;
map<int ,bool>vis;
map<int,int>extraatk;
map<int,int>extradex;
map<int ,int>extramdef;
*/
int *f;
int *pre;
int *extraatk;
int *extradex;
int *extramdef;
bool vis[maxx];
int cnt=0;
bool vis1[20][20]={};
int hp0=728,atk0=11,dex0=11,mdef0=0;//初始能力
//int hp0=580,atk0=80,dex0=51,mdef0=105;//初始能力
int ans=0;
bool minusdamage=0;
struct enemy{
int hp,atk,dex,spj;
double spj2[14];
}enemys[44]={};
int tou,wei,*q1,*q2,*q3;
int st0=0;
struct ff{
int x,y;}q[3333]={};
void calc1()
{
for(int i=1;i<=siz;i++)
pos[i][0]=pos[i][i]=1;
}
//int enemy0[99]={5,9,7,8,6,7,7,1,9,10,8,2,7,3,4,8};
int enemy0[99]={1,2,3,7,0,4,1,8,2,1,0,5,0,8,0,7,4,7,2,3,0,8,6,2};
int weak[99]={};
int fight2(int myhp,int myatk,int mydex,int mymdef,enemy id,int weak=0)
{
//printf("%d\n",++cnt);
int klk=0;
if(myhp<=0)return 0;
double damagerate=1;
double extradamage=0;//固伤,魔防有效
double extradamage2=0;//固伤,无视魔防
if(myatk<=id.dex)return 0;
if(id.spj==2147483647)
return myhp+id.spj2[0];
for(int i=0;i<effects;i++)
if(id.spj&(1<<i))
switch(i)
{
case 1://魔攻
mydex=0;break;
case 7://净化
extradamage+=mymdef*id.spj2[klk++];
break;
case 2://固伤
extradamage2+=id.spj2[klk++];
break;
case 3://吸血,不加到自己生命
myhp=myhp-(int)(myhp*(id.spj2[klk++]));
break;
case 4://吸血,加到自己生命
id.hp+=myhp*id.spj2[klk++];
//myhp=myhp*(1-id.spj2[klk++]);
myhp=myhp-(int)(myhp*(id.spj2[klk++]));
break;
case 5://X连击
damagerate=id.spj2[klk++];
break;
case 6://坚固
myatk=id.dex+1;
break;
case 0://模仿
id.atk=max(id.atk,myatk);
id.dex=max(id.dex,mydex);
break;
case 8://先攻
id.hp+=myatk-id.dex;
break;
case 9://破甲
extradamage+=id.spj2[klk++]*mydex;
break;
case 10://反击
extradamage+=((id.hp-1)/(myatk-id.dex)+1)*(int)(myatk*id.spj2[klk++]);
break;
}
if(myatk-id.dex<=0)return 0;
int alldamage=(id.hp-1)/(myatk-id.dex)*(id.atk-mydex)*damagerate-mymdef;
alldamage+=extradamage;
if(alldamage<0&&!minusdamage)
alldamage=0;
alldamage+=extradamage2;
if(myhp-alldamage<=0)return 0;
else return myhp-alldamage;
}
int fight(int myhp,int myatk,int mydex,int mymdef,enemy id,int tmm=0)
{
switch(tmm)
{
case 8:
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
return myhp;
case 9:
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
return myhp;
case 6:
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[4]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[0]);
return myhp;
case 7:
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[1]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[3]);
myhp=fight2(myhp,myatk,mydex,mymdef,enemys[5]);
return myhp;
default:
return fight2(myhp,myatk,mydex,mymdef,id);
}
}
char map0[13][13]={//5,6,7宝石,1-4血瓶
{19,19,5,0,6,19,20,19,19,1,0,5,20},
{19,19,19,19,0,0,0,20,0,19,1,19,6},
{19,19,19,1,0,19,19,20,0,20,0,19,0},
{5,0,19,0,20,19,5,1,19,20,19,19,19},
{20,19,19,19,0,19,19,19,19,0,19,19,0},
{0,0,20,19,20,19,19,19,0,0,0,20,2},
{20,19,19,19,0,19,19,19,19,19,6,0,19},
{0,1,0,0,0,19,20,0,20,0,20,19,5},
{20,19,19,19,20,0,0,19,20,19,6,20,0},
{6,20,0,0,0,19,0,19,19,19,0,19,19},
{0,19,20,19,19,0,0,19,0,2,20,20,0},
{20,19,0,19,0,0,0,19,19,19,19,19,5},
{0,0,0,0,0,0,0,0,19,0,0,0,5},
};
char map1[13][13]={};
bool check(int s,int i)
{
if(st0&(1<<i))
return true;
for(int j=0;j<siz;j++)
if(i!=j&&graph[i][j])
return true;
return false;
}
void bfs(int x,int y,char map11[13][13])
{
int tou=0,wei=0;
memset(vis1,0,sizeof(vis1));
vis1[x][y]=1;
q[0].x=x,q[0].y=y;
while(tou<=wei)
{
int tx=q[tou].x,ty=q[tou].y;
if(tx>0&&!vis1[tx-1][ty])
{
vis1[tx-1][ty]=1;
if(map11[tx-1][ty]<19)
q[++wei].x=tx-1,q[wei].y=ty;
}
if(tx<12&&!vis1[tx+1][ty])
{
vis1[tx+1][ty]=1;
if(map11[tx+1][ty]<19)
q[++wei].x=tx+1,q[wei].y=ty;
}
if(ty>0&&!vis1[tx][ty-1])
{
vis1[tx][ty-1]=1;
if(map11[tx][ty-1]<19)
q[++wei].x=tx,q[wei].y=ty-1;
}
if(ty<12&&!vis1[tx][ty+1])
{
vis1[tx][ty+1]=1;
if(map11[tx][ty+1]<19)
q[++wei].x=tx,q[wei].y=ty+1;
}
tou++;
}
}
void makegraph()
{
int idd=19;
for(int i=12;i>=0;i--)
for(int j=0;j<=12;j++)
if(map0[i][j]==20)
map0[i][j]=++idd,siz++;
for(int i=0;i<=12;i++)
for(int j=0;j<=12;j++)
if(map0[i][j]>19){
bfs(i,j,map0);
int tm=map0[i][j]-20;
for(int i=0;i<=12;i++)
for(int j=0;j<=12;j++)
if(vis1[i][j]&&map0[i][j]>19)
graph[tm][map0[i][j]-20]=graph[map0[i][j]-20][tm]=1;
}
bfs(12,6,map0);
for(int i=0;i<=12;i++)
for(int j=0;j<=12;j++)
if(map0[i][j]>19&&vis1[i][j])
st0|=(1<<map0[i][j]-20);
}
bool check0(int st,int add)
{
if(st0&(1<<add))return 1;
for(int i=0;i<siz;i++)
if((st&(1<<i))&&graph[i][add])
return true;
return false;
}
int getserv(int st)
{
if(st==0x3ffffff)
int dfgasdg=0;
memcpy(map1,map0,sizeof(map0));
for(int i=0;i<13;i++)
for(int j=0;j<13;j++)
if(map1[i][j]>19)
{
int tm=map1[i][j]-20;
if(st&(1<<tm))
map1[i][j]=0;
}
bfs(12,6,map1);
int tmphp=0;
int atk=0,dex=0,mdef=0;
for(int i=0;i<13;i++)
for(int j=0;j<13;j++)
if(vis1[i][j])
switch(map0[i][j])
{
case 5:
atk+=atk1;
break;
case 6:
dex+=dex1;
break;
case 7:
mdef+=mdef1;
break;
case 1:
tmphp+=hp1;
break;
case 2:
tmphp+=hp2;
break;
case 3:
tmphp+=hp3;
break;
case 4:
tmphp+=hp4;
break;
}
extraatk[st]=atk;
extradex[st]=dex;
return tmphp;
}
bool uuuu(int s,int t)
{
for(int i=0;i<siz;i++)
if((s&(1<<i))==0&&(t&(1<<i))>0)
return 1;
return 0;
}
bool isfinish(int i)//自定义函数,表示状态i可以作为最终状态,那么可以比较最终结果
{
return((i>>22)&1)==1;
}
void dp(int x)
{
q3=q1,q1=q2,q2=q3;//q1新,q2旧
int allsiz=wei;
tou=0,wei=-1;
for(int i=0;i<=allsiz;i++)//提取上一层dp结果
{
int te=q2[i];
if(f[te]==0&&f[te|maxx]==0)
continue;
for(int j=0;j<siz;j++)
{
int tm=te|(1<<j);
if(tm!=te&&!vis[tm])
{
vis[tm]=1;
if(check0(te,j))
q1[++wei]=tm;
}
}
}
//多线程
for(int i=0;i<=wei;i++)
{
int te=q1[i];//队列不计入衰弱
addhp[te]=getserv(te);
if(te==0x216006)
int agadsgsd=0;
for(int j=0;j<siz;j++)
if(te&(1<<j))
{
int tm=te^(1<<j);
int tmm=enemy0[j];
if(tmm>=8)
{
if(f[tm]>0&&f[tm]+addhp[te]-addhp[tm]>f[te])
f[te]=f[tm]+addhp[te]-addhp[tm],pre[te]=tm,extramdef[te]=extramdef[tm]+mdef1;
continue;
}
int tmp=fight2(f[tm],extraatk[tm]+atk0,extradex[tm]+dex0,extramdef[tm]+mdef0,enemys[enemy0[j]],tmm);
if(tmp>0)
tmp=tmp+addhp[te]-addhp[tm];//不衰弱里打
if(tmp>f[te])//转移
f[te]=tmp,pre[te]=tm,extramdef[te]=extramdef[tm];
}
if(f[te]>0)//如果这个状态能走到
{
fprintf(dbg,"%x %d %d %d %d %x\n",te,f[te],atk0+extraatk[te],dex0+extradex[te],mdef0+extramdef[te],pre[te]);
if(isfinish(te))//可以是最终状态
{
if(ans<f[te])//lock
ans=f[te],pos0=te;
}
}
}
//多线程
}
void getpos(int s)
{
while(s)
{
int ss=pre[s];
int sss=(s^ss)&maxx-1;
for(int i=0;i<=12;i++)
for(int j=0;j<=12;j++)
if(sss==(1<<map0[i][j]-20)&&map0[i][j]>19)
printf("%x %x (%d,%d),hp=%d,atk=%d,dex=%d,mdef=%d\n",s,pre[s],i,j,f[ss],extraatk[ss&maxx-1]+atk0,extradex[ss&maxx-1]+dex0,extramdef[ss&maxx-1]+mdef0);
s=pre[s];
}
}
int main()
{
f=new int[1LL*maxx*2-1];
pre=new int[1LL*maxx*2-1];
extraatk=new int[maxx];
extradex=new int[maxx];
extramdef=new int[maxx];
addhp=new int[maxx];
memset(f,0,sizeof(int)*(1LL*maxx*2-1));
memset(pre,0,sizeof(int)*(1LL*maxx*2-1));
memset(extraatk,0,sizeof(int)*maxx);
memset(extradex,0,sizeof(int)*maxx);
memset(extramdef,0,sizeof(int)*maxx);
memset(addhp,0,sizeof(int)*maxx);
q1=new int[2999999];
q2=new int[2999999];
enemys[0]={55,18,3,0,{}};
enemys[1]={35,22,5,0,{}};
enemys[2]={92,14,8,(1<<8)+(1<<10),{0.1}};
enemys[3]={50,29,1,(1<<5)+(1<<7),{2,3}};
enemys[4]={68,34,4,0,{}};
enemys[5]={50,70,0,0,{}};
enemys[6]={95,96,8,0,{}};
enemys[7]={23,18,11,1<<6,{}};
makegraph();
q1[0]=0,tou=0,wei=0;
dbg=fopen("debug.log","wb");
for(int i=0;i<siz;i++)
{
for(int j=0;j<siz;j++)
fprintf(dbg,"%d ",graph[i][j]);
fprintf(dbg,"\n");
}
for(int i=0;i<siz;i++)
if(st0&(1<<i))
fprintf(dbg,"%d ",i);
fprintf(dbg,"\n");
f[0]=hp0;
for(int i=1;i<=siz;i++)
dp(i);
//dp();
printf("%x %d\n",pos0,ans);
getpos(pos0);
}