1. 程式人生 > >AC Challenge [ ACM-ICPC 2018 南京賽區網路預賽 ] [dfs + 二進位制記憶化搜尋 ]

AC Challenge [ ACM-ICPC 2018 南京賽區網路預賽 ] [dfs + 二進位制記憶化搜尋 ]

這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
這裡寫圖片描述
題意:有n個問題,做第i個問題得分是t*a[i]+bi,
但是做第i題之前還需要先做其他的一些題目….可以選擇不做完所有的題,問最後的最高得分.
思路:深搜就可以了,跟很多深搜的問題一樣,有很多重複的子問題,此題的記憶化很奇特用的二進位制類似狀壓的思想

AC code:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>

using namespace std
; typedef long long ll; const int maxn = 22; struct node{ int a,b; }ss[maxn]; int in[maxn]; bool vis[maxn]; vector<int>G[maxn]; ll ans = 0 ,sum[1<<22]; int t; void dfs(ll pos,ll res,ll Tforce) { ans = max(ans,res); if(sum[Tforce] > res) return; sum[Tforce] = res; for
(int i = 1; i <= t ;i++) { if ( !in[i] && !vis[i] ) { int len = G[i].size(); vis[i] = true; for (int j = 0;j<len;j++) in[G[i][j]]--; dfs(pos+1,res+ss[i].a*pos+ss[i].b,Tforce|(1<<i)); vis[i] = false; for (int j = 0
;j<len;j++) in[G[i][j]]++; } } } int main(){ memset(in,0,sizeof(in)); memset(sum,0,sizeof(sum)); memset(vis,false,sizeof(vis)); scanf("%d",&t); int len; for (int i = 1;i<=t;i++) { scanf("%d %d %d",&ss[i].a,&ss[i].b,&len); int v; for (int j = 0 ; j < len ; j++) { scanf("%d",&v); G[v].push_back(i); in[i]++; } } dfs(1,0,0); printf("%lld\n",ans); return 0;