圖論 - 教科書般的褻瀆 - 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;
}
相關文章
- 洛谷P4593 [TJOI2018]教科書般的褻瀆(拉格朗日插值)
- 拆解任天堂教科書般的介面動效設計
- 《雨中冒險》: 教科書式好玩的Roguelike遊戲遊戲
- 以《遺蹟2》和《神之褻瀆2》為例 為什麼很多系列都是2代才變得成熟?
- 教科書級講解,秒懂最詳細Java的註解Java
- 過於自嗨的《紫塞秋風》,怎麼就成了行業教科書?行業
- 教科書的典範:瑞幸咖啡曾經是怎麼向歐美韭菜吹牛的
- 集20年之大成,這是一本開源的演算法教科書演算法
- 《雙人成行》如何煉就“教科書級別的合作體驗遊戲”典範?遊戲
- 向安全攻擊說NO,請翻開體系化防禦的三頁“教科書”
- 騰訊下架32款遊戲:一場教科書式的公關化妝術遊戲
- 遊戲輕量化教科書:雲頂之弈為什麼可以這麼火?遊戲
- 粵教版電子書
- 講個大部分資料結構和演算法教科書中都不會講的問題資料結構演算法
- 遊戲即藝術,深度解讀《地平線:零之曙光》這款"視覺教科書"遊戲視覺
- Victory被美教科書出版商“收入囊中”,下一站是亞洲VR教育市場VR
- 【論文閱讀】CVPR2022: Learning from all vehicles
- 日榜免費第一、暢銷第十,它為IP改編手遊做出了教科書級的示範
- SSL證書是什麼?SSL證書一般要多少錢?
- 【圖論】樹的重心圖論
- ¡Hola Euler! 圖資料庫的理論基礎:圖論資料庫圖論
- 圖論圖論
- 圖論之有權圖「帶權圖的表示」圖論
- 購買https 證書一般需要多少錢HTTP
- [論文翻譯][1809 09294]Object Detection from Scratch with Deep SupervisionObject
- pygame 教學 匯入圖片GAM
- 圖書
- ILSSI認證和一般的證書有什麼區別?
- 圖論——圖的基本性質與表示圖論
- 般四己嚴集程部海圖些式廣表候便美不求利我科條所文
- 【圖論】尤拉圖圖論
- 遊戲創新的一般方法論,本質就是排列組合?遊戲
- 神From不再 From Software的內憂與外患
- 論文閱讀翻譯之Deep reinforcement learning from human preferences
- 10244圖論圖論
- 模板 - 圖論圖論
- 【模板】圖論圖論
- 圖論板子圖論