1. 程式人生 > >解題:2018九省聯考 一雙木棋

解題:2018九省聯考 一雙木棋

turn 討論 names ret tps 高端 scanf 分享圖片 std

題面

我的常數可能是沒救了,明明寫的差不多,別人的都跑的飛快,就我的T到爆炸,卡常也卡不過去QAQ

我當初這個題手動討論拿了25pts,然後胡亂貪心搞了5pts 2333

還以為min-max對抗搜索是什麽高端的東西,其實就是記錄一下行動方,然後對應的在決策時取min/max

這個題可以證明狀態量只有三十多萬,於是加上一個記憶化就好了,大概可以狀壓,也可以哈希+map(我感覺我該寫狀壓的,map不開O2慢的爆炸......)

技術分享圖片
// luogu-judger-enable-o2
#include<map>
#include<cstdio>
#include<cstring>
#include
<algorithm> using namespace std; const int N=12,bas=11,inf=1e9; int c[N][N],f[N][N],last[N],n,m; map<long long,int> mp; inline long long Ghash() { long long hsh=0; for(int i=1;i<=n;i++) hsh=hsh*bas+last[i]; return hsh; } inline int maxi(int a,int b) { return a>b?a:b; } inline
int mini(int a,int b) { return a<b?a:b; } inline int dosth(long long s) { int ret=0; for(int i=n;i;i--) last[i]=s%bas,s/=bas,ret+=last[i]; return ret&1; } int DFS(long long s) { if(mp.find(s)!=mp.end()) return mp[s]; int mov=dosth(s),noww=mov?inf:-inf;
for(int i=1;i<=n;i++) if(last[i]<last[i-1]) { last[i]++; long long news=Ghash(); noww=mov?mini(noww,DFS(news)-c[i][last[i]]): maxi(noww,DFS(news)+f[i][last[i]]); last[i]--; } return mp[s]=noww; } int main () { register int i,j; scanf("%d%d",&n,&m); for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&f[i][j]); for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&c[i][j]); for(i=0;i<=n;i++) last[i]=m; DFS(mp[Ghash()]=0),printf("%d",mp[0]); return 0; }
View Code

解題:2018九省聯考 一雙木棋