首先因為每個值只會被算一次且值的個數為\(n^2\)級別的,因此我們可以對每個\(d_\)開乙個點,之後就可以用最大權閉合子圖做。
考慮題目的限制:
1.選擇乙個區間\([l,r]\)會將\(\sum\limits_^\sum\limits_^rd_\)選上:
我們顯然不能全部連上,這是\(n^4\)級別的,我們可以只從\(d_\)向\(d_\)和\(d_\)連邊。
2.如果吃過\(c\)種代號為\(x\)的壽司,會付出\(m*x^2+c*x\)的代價:
拆成兩部分:
<1>選了\(c\)種代號為\(x\)的壽司會付出\(c*x\)的代價,即選了\(d_\)就必定要付出\(a_i\)的代價。
<2>如果選了代號為\(x\)的壽司,就會付出\(m*x^2\)的代價:
我們對每個\(a_i\)也開乙個點,點權為\(-a_i^2\)。
於是總結下連邊是這樣的:
對於\(d_\):
如果\(i=j\):
從\(d_\)向\(a_i\)連一條容量為\(inf\)的邊,表示選了第\(i\)個就選了第\(a_i\)種。從\(d_\)向匯點連一條容量為\(a_i\)的邊,表示選了\(i\)號壽司需要付出\(a_i\)的代價。
反之:從\(d_\)向\(d_\)和\(d_\)連容量為\(inf\)的邊。
最後根據點權正負向源點和匯點連邊。
code:
#includeusing namespace std;
const int maxn=110;
const int inf=1e9;
int n,m,num,cnt=1,s,t,tot,ans;
int a[maxn],head[maxn*maxn+maxn],cur[maxn*maxn+maxn],dep[maxn*maxn+maxn];
int val[maxn][maxn],id[maxn][maxn];
struct edgee[(maxn*maxn+maxn)<<2];
inline void add(int u,int v,int w)
inline bool bfs()
}return dep[t]>0;
}int dfs(int x,int goal,int lim)
return lim-res;
}inline int dinic()
int main()
else
if(w>=0)ans+=w,add(s,id[i][j],w),add(id[i][j],s,0);
else add(id[i][j],t,-w),add(t,id[i][j],0);
} if(m)
for(int i=1;i<=num;i++)
add(tot+i,t,i*i),add(t,tot,0);
printf("%d",ans-dinic());
return 0;
}
六省聯考 2017 壽司餐廳
戳我 簡要題目 乙個序列,可以若干次取其中一段區間,區間及其子集的價值都會被統計進去且每個區間的價值只能被統計一次。如果你拿 c 種 x 數,你需要花費 m x 2 c x 的代價。求最大價值。這道題看起來並沒有思路,看了看題解後發現這是最大權閉合子圖。what?這是神馬?不會,於是去學了一下。然後...
六省聯考2017 壽司餐廳
感覺有難度的一道網路流 自己的網路流水平還是遠遠不夠 一開始以為是費用流搞了半天,發現無法處理只有第一次有效的情況 於是看題解才知道就是個最大權閉合子圖 由於每種東西都只有第一次有效 那麼我們可以考慮把區間作為點建圖 考慮最大權閉合子圖的模型 選擇區間 i,j 的貢獻就一定要選擇區間 i 1,j i...
六省聯考 壽司餐廳
太長了,不描述!看題面看了10min才反應過來這是個最大權值閉合子圖的問題 應用網路流最小割的模型來解決本問題 首先,每個壽司編號即為器材,代價為 w i w i m 那麼我們由每個壽司編號向匯點鏈結一條容量為w i w i m 每個壽司一定需要乙個壽司編號,代價為 w i 那麼我們由壽司向壽司編號...