NKOI 3720 UVA 11825 黑客的攻擊

2021-07-15 07:49:46 字數 1222 閱讀 3900

題目描述:

假設假設你是乙個黑客,侵入了乙個有著n臺計算機(編號0,1,...,n-1)的網路。一共有n種服務,每台計算機都執行著所有服務。對於每台計算機,你都可以選擇一項服務,終止這台計算機和所有與它相鄰計算機的該項服務(如果其中一些服務已經停止,則這些服務繼續處於停止狀態)。你的目標是讓盡量多的服務完全癱瘓(即:沒有任何計算機執行該項服務)。

輸入格式:

輸入包含多組資料

每組資料的第一行為整數n(1<=n<=16):以下n行每行描述一台計算機的相鄰計算機,其中第乙個數m為相鄰計算機的個數,接下來m個整數為這些計算機的編號。

輸入結束的標誌是n=0。

輸出格式:

對於每組資料,輸出完全癱瘓的伺服器的最大數量

樣例輸入:

3

2 1 2

2 0 2

2 0 1

41 1

1 01 3

1 20

樣例輸出:

case 1: 3

case 2: 2

首先考慮本題的數學模型:

設集合pi為計算機i以及其相鄰計算機的集合,設全集為n(即所有伺服器的全集)

把n個集合p1,p2……pn分成盡量多組,使得每組中的所有集合的並集等於全集,每組對應題目中的一項服務

那麼我們就用二進位制來進行狀態壓縮

用f[s]表示子集s最多可以分成多少組,我們可以得到:

f[s]=max(f[s-s0])+1 其中s0是s的子集,cover[s0]等於全集

#include#include#includeusing namespace std;

const int maxn=(1<<16)+5;

int n,m,x,s,s0,cases;

int p[maxn],cover[maxn],f[maxn];//p陣列即為上文中的p集合,cover[s]表示若干pi的集合s中所有pi的並集

void clean()

int main(){

while(scanf("%d",&n)&&n){

clean();

int i,j,point=(1<

NKOI 防守馬克

題目略 我最早其實想的貪心,力量從大到小,從下到上放置奶牛,但是如果有乙隻力量小的奶牛非常重,就矛盾。狀壓dp基礎題,但是開始我一直沒有想到運用列舉頂端的奶牛進行狀態轉移。我發現其實題目中物件增長的方式可以給狀態轉移帶來啟發,比如這裡的奶牛就是乙隻只疊上去的嘛。另外我還發現其實驗證dp是否可行就是看...

NKOI 1349 工作安排

uasco 2009 open gold 2 工作安排 time limit 10000ms memory limit 65536k total submit 63 accepted 43 case time limit 1000ms description farmer john 有太多的工作要做...

NKOI 3645 黑盒序列

黑盒序列 time limit 10000ms memory limit 65536k total submit 4 accepted 4 case time limit 1000ms description 有乙個只能存放整數的序列叫 黑盒序列 一開始序列為空。對於該序列,我們有add和get兩種...