哇村經常遭遇風沙,沙塵暴嚴重阻礙了哇村的經濟發展。 wowo村前面有一片森林,這片森林可以防止風沙侵襲。 但是有乙個規則,即森林中最高的樹木數量應該超過所有樹木的一半,這樣才能防止風沙侵襲。 砍伐一棵樹需要花費一定的錢。 不同種類的樹木花費不同的錢。 哇村也很窮。 有n種樹木。 第i種樹的數量是,第i種樹的高度,減少一種第i種樹的成本。 (注意:「砍伐樹木」意味著從森林中移除樹木,不能將樹木切割成另乙個高度。)
思路:我們按照高度進行排序,從低到高列舉哪種高度的樹是答案,以花費為權值建立線段樹,由於c<=200,所以不用離散化就行。假設當前需要砍k棵樹,那麼每次查詢優先選著花費低的樹,取min就行了。當然範圍小不用線段樹也是可以的。
#includeusing namespace std;
typedef long long ll;
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1|1
const int maxn = 2e5 + 10;
const int mod = 1e9;
const int inf = 0x3f3f3f3f;
struct node
}a[maxn];
ll sum[maxn << 2], cost[maxn], num[maxn]; //區間和
ll cnt[maxn << 2]; //維護區間裡的數的出現次數
mapmp, mp1;
void build(int l, int r, int rt)
void update(ll pos, ll val, int l, int r, int rt)
int mid = (l + r) >> 1;
if(pos <= mid)
update(pos, val, lson);
else
update(pos, val, rson);
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}ll query(ll k, int l, int r, int rt)
int mid = (l + r) >> 1;
if(cnt[rt << 1] >= k)
return query(k, lson);
else
return (ll)query(k - cnt[rt << 1], rson) + sum[rt << 1];
}int main()
sort(a + 1, a + n + 1);
cost[n + 1] = 0, num[n + 1] = 0;
for(int i = n; i >= 1; --i)
ll ans = 0x3f3f3f3f3f3f3f3f;
for(int i = 1; i <= n; ++i)
ll c = cost[i] - mp[a[i].h]; //當前花費
ll tmp = mp1[a[i].h]; //當前數量
ll nn = num[1] - num[i] + tmp; //當前剩餘總數
ll tot = 0;
if(nn - 2 * tmp + 1 > 0)
tot = query(nn - 2 * tmp + 1, 1, n, 1);
ans = min(ans, tot + c);
update(a[i].c, a[i].num, 1, n, 1);
}printf("%lld\n", ans);
}return 0;
}
牛客網 華為機試 020 牛客網
密碼要求 1.長度超過8位 2.包括大小寫字母.數字.其它符號,以上四種至少三種 3.不能有相同長度超2的子串重複 說明 長度超過2的子串 一組或多組長度超過2的子符串。每組佔一行 如果符合要求輸出 ok,否則輸出ng 示例1 021abc9000 021abc9abc1 021abc9000 02...
牛客網 乳酪
題目很簡單,中文題。複製了 乳酪之間距離不用管,只要開個並查集維護就好了,另外需要選好幾個點作為起點幾個點作為終點。o n 2 的建圖。感覺可以平面掃瞄。有空去試試。以下 ac includeusing namespace std const int maxn 1e5 5 define ll lon...
牛客網 A 招生
第一行,三個正整數n,m,p.後面n行,每行兩個正整數數a i,b i a i b i 分別表示第i個人的高考分和校測分。一行乙個數,表示答案 小a高考至少要考多少分。輸入6 3 750 700 530 683 625 703 620 699 623 710 538 654 599 輸出 inclu...