b_lg_連續攻擊遊戲(反向思維+記憶化搜尋)
阿新 • • 發佈:2020-10-13
一開始的時候,lxhgww只能使用某個屬性值為1的裝備攻擊boss,然後只能使用某個屬性值為2的裝備攻擊boss,
然後只能使用某個屬性值為3的裝備攻擊boss……以此類推。現在lxhgww想知道他最多能連續攻擊boss多少次?
思路
這本是一道二分圖的題,但我很生氣我沒學過,所以一氣之下寫了個50/100的正向暴搜
#include<bits/stdc++.h> using namespace std; const int N=1e7+5; int n, a[N][2], st[N], ans; void dfs(int attr) { if (attr>ans) ans=attr; for (int j=1; j<=n; j++) if (!st[j] && (attr+1==a[j][0] || attr+1==a[j][1])) { st[j]=1; dfs(attr+1); st[j]=0; } } int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); cin>>n; for (int i=1; i<=n; i++) cin>>a[i][0]>>a[i][1]; for (int i=1; i<=n; i++) if (a[i][0]==1 || a[i][1]==1) { st[i]=1; dfs(1); st[i]=0; } cout<<ans; return 0; }
想著加入記憶化加速,但上面的程式碼即使加入記憶化也無法擺脫main函式中的for迴圈
反向思維優化:將每個武器的屬性和屬性id換過來儲存,即 a[x].push_back(id), a[y].push_back(id)
#include<bits/stdc++.h> using namespace std; const int N=1e6+5; int st[N], f[N], ans; vector<int> a[N]; int dfs(int attr) { if (f[attr]) return f[attr]; int t=0; for (int& id : a[attr]) if (!st[id]) { //該attr對應的武器編號 st[id]=1; t=max(t,dfs(attr+1)+1); st[id]=0; } return f[attr]=t; } int main() { std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin>>n; for (int i=1; i<=n; i++) { int x,y; cin>>x>>y; a[x].push_back(i), a[y].push_back(i); } cout<<dfs(1); return 0; }