解題:2018九省聯考 一雙木棋
阿新 • • 發佈:2018-10-16
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> #includeView Code<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; } inlineint 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; }
解題:2018九省聯考 一雙木棋