圖論 - 教科書般的褻瀆 - from jisuanke
環境裡有 n 個怪物,他們的生命值用一個正整數表示。現在,你可以使用兩種魔法,對怪物進行攻擊。當怪物的生命值小於等於 0 時,他便被消滅了。
魔法箭,對摸個生物造成 k 點傷害,對一個生物最多使用一次,但沒有使用次數限制。
褻瀆,對所有生物造成一點傷害,如果殺死了某個生物,則繼續自動重新使用該法術。只能主動使用一次,且必須最後使用。
請問,最多能消滅多少個怪物?褻瀆法術最多能釋放幾次?
輸入格式
第一行兩個整數 n 和 k ,表示怪物的數量和法術的傷害。第二行 n 個正整數,依次表示每個怪物的生命值。
輸出格式
一行,兩個整數,表示最多能消滅多少怪物和褻瀆法術最多被釋放的次數。
資料範圍
對於 40% 的資料 n≤200 。
對於全部資料, n,k≤100000, 怪物的生命上限為 100000。
樣例輸入
5 1 1 2 3 5 7
樣例輸出
4 5
建圖: 把血量看作點,對於 ai > k,連線 ai 和 ai - k
這樣,圖將會分成若干個聯通塊,分別考察每一個聯通塊:
1:這個聯通塊具有不少於節點數量的邊數,則這些節點代表血量都可以取到;
2:這個聯通是樹,還有兩種情況:
(1):聯通塊中的點,在給定序列中出現次數超過聯通塊中邊數(這種情況是由於此聯通塊中最小點無法向更低血量連邊而出現的),這些節點代表的血量同樣都可以取到;
(2): otherwise,序列出現次數 = 邊數,這個聯通塊有一個點會無法取到,簡單的貪心策略,不取塊中的最大血量。
綜合以上的判斷方式,我們可以得知最佳處理下會得到哪些血量,進而求得了褻瀆次數。
同時,可以證明,採取這種操作可以殺死最多的怪物。
Code
#include <iostream>
#include <vector>
using namespace std;
#define REP(i, a, b) for (int i = (a), i##_end_ = (b); i < i##_end_; ++i)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define mp make_pair
#define x first
#define y second
#define pb push_back
#define SZ(x) (int((x).size()))
#define ALL(x) (x).begin(), (x).end()
#define max(a, b) (a > b ? a : b)
#define min(a, b) (a < b ? a : b)
typedef long long LL;
const int N = 120000;
int n, k, cnt, ans1, ans2;
int a[N], vis[N], vtx[N], egs[N], mxn[N];
bool tree[N], ok[N];
vector< vector<int> > edges(N);
void dfs(int cur, int fa, int tag) {
vis[cur] = tag;
REP(i, 0, edges[cur].size()) {
int vertex = edges[cur][i];
if (vis[vertex] && vertex != fa) tree[tag] = false;
if (!vis[vertex]) dfs(vertex, cur, tag);
}
}
int main() {
memset(tree, 1, sizeof tree);
scanf("%d%d", &n, &k);
REP(i, 1, n + 1) scanf("%d", &a[i]);
REP(i, 1, n + 1)
if (a[i] > k)
edges[a[i]].pb(a[i] - k),
edges[a[i] - k].pb(a[i]);
REP(i, 1, N) if (!vis[i]) dfs(i, 0, ++cnt);
REP(i, 1, n + 1) vtx[vis[a[i]]]++;
REP(i, 1, n + 1) if (a[i] > k) egs[vis[a[i]]]++;
REP(i, 1, N) mxn[vis[i]] = max(mxn[vis[i]], i);
REP(i, 1, N)
if (vtx[vis[i]] > egs[vis[i]]) ok[i] = true;
else if (tree[vis[i]] && i == mxn[vis[i]]) ok[i] = false;
else ok[i] = true;
REP(i, 1, N) if (ok[i] == false) { ans2 = i - 1; break; }
REP(i, 1, n + 1) if (a[i] - k <= ans2) ans1++;
cout << ans1 << " " << ans2 + 1 << endl;
return 0;
}
相關文章
- 拆解任天堂教科書般的介面動效設計
- Grammarly:研究顯示川普支持者更喜歡使用褻瀆語言
- 《雨中冒險》: 教科書式好玩的Roguelike遊戲遊戲
- IT教科書版的杜拉拉昇職記——評《遠大前程》
- 教科書級講解,秒懂最詳細Java的註解Java
- 使用MongoDB血淚般的經驗教訓MongoDB
- 騰訊下架32款遊戲:一場教科書式的公關化妝術遊戲
- 過於自嗨的《紫塞秋風》,怎麼就成了行業教科書?行業
- 《雙人成行》如何煉就“教科書級別的合作體驗遊戲”典範?遊戲
- 集20年之大成,這是一本開源的演算法教科書演算法
- 遊戲輕量化教科書:雲頂之弈為什麼可以這麼火?遊戲
- 美聯社:蘋果或將受益於美國未來五年的電子教科書發展蘋果
- 計算機體系結構:量化研究方法(第5版) ——與時俱進的教科書計算機
- Word文書處理教學--精確改變圖片的位置(轉)
- O'Reilly精品圖書推薦:資料科學入門資料科學
- 請教:jive論壇的同步機制
- 請教:事務的完整性一般怎麼實現?
- 遊戲即藝術,深度解讀《地平線:零之曙光》這款"視覺教科書"遊戲視覺
- 講個大部分資料結構和演算法教科書中都不會講的問題資料結構演算法
- From Apprentice To Artisan 一書個人理解APP
- 圖書 "ERP理論 方法與實踐" 目錄
- Nielsen:資料顯示71%學生使用者希望平板電腦取代傳統教科書
- 基督教筆記(八):基督教科學派(Christian Science)筆記
- 日榜免費第一、暢銷第十,它為IP改編手遊做出了教科書級的示範
- SSL證書是什麼?SSL證書一般要多少錢?
- JS中圖片壓縮的一般方法JS
- 《褻神》:故事氛圍比遊戲難度更加“受苦”遊戲
- 我的圖靈圖書列表圖靈
- 【圖論】樹的重心圖論
- 圖論圖論
- ¡Hola Euler! 圖資料庫的理論基礎:圖論資料庫圖論
- 維基百科,自由的百科全書 - 儲存空間的換算
- C++期末大作業 圖書評論和推薦系統C++
- 關於資料科學的十本好書資料科學
- 遊戲創新的一般方法論,本質就是排列組合?遊戲
- 遊戲論·性/別丨非一般向遊戲批判遊戲
- 圖論之有權圖「帶權圖的表示」圖論
- 我的圖靈書圖靈