liftleaf
"I want you to name it, I do"
by __chang___
選擇當下看起來最好的做法
局部最佳的作法也是全部最佳的作法
如果題目有反例,就不能用貪婪演算法
我們需要具體的東ㄒ🤣
給你一排藥水,藥水的數字代表喝下去後你的生命值的增加量
藥水的生命可能正可能負。
過程中完全不能讓生命值變成負的情況下,你最多可以喝幾瓶藥水?
每個都先照順序加起來ㄅ
發現生命值變負了,再回去把生命值最小的捨棄掉不喝
反悔貪婪!
怎麼找到陣列中最小的數字?😧
用priority_queue把數字由小存到大(邊跑邊存)
i | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
arr[i] | 8 | -7 | 1 | -4 | -6 |
sum | 8 | 1 | 2 | -2 | -8 |
ANS:
0
1
2
3
3
3
priority_queue存的內容:
8
8
-7
-7
1
8
-7
-4
1
8
-6
-4
1
8
+7
+7
+7
+7
+6
i | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
arr[i] | 8 | -7 | 1 | -4 | -6 |
sum | 8 | 1 | 2 | -2 | -8 |
ANS:
0
1
2
3
3
3
priority_queue存的內容:
8
8
-7
-7
1
8
-7
-4
1
8
-6
-4
1
8
+7
+7
+7
+7
+6
#include<iostream>
#include<queue>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int n;cin>>n;
long long int arr[n]={0};
priority_queue<long long int,vector<long long int>,greater<long long int> > pq;
long long int sum=0,ans=n;
for(int i=0;i<n;i++){
cin>>arr[i];
pq.push(arr[i]);
sum+=arr[i];
while(sum<0){
sum-=pq.top();
pq.pop();
ans--;
}
}
cout<<ans<<'\n';
return 0;
}
看起來像是初學者寫的扣 別噴😅
給你兩個陣列,請問各取一數所得的差最小是多少?
先把兩個陣列的數字由小排到大(sorting algorithm😋)
然後開始計算兩個數字之差
接著,有比較小的數字的陣列,將index往後一格
偵測到一個陣列的最後一個index為止
雙指針!
MIN DIF:
index | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
a[i] | 1 | 5 | 7 | 8 | 11 |
b[j] | 3 | 3 | 10 | 15 | 17 |
index | 0 | 1 | 2 | 3 | 4 |
---|---|---|---|---|---|
a[i] | 1 | 5 | 7 | 8 | 11 |
b[j] | 3 | 3 | 10 | 15 | 17 |
2
CURRENT DIF:
2
2
5
3
2
1
2
2
2
2
2
2
1
#include<iostream>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);
int n;cin>>n;
long long int a[n]={0},sum=0;
for(int i=0;i<n;i++)cin>>a[i];
for(int i=0;i<n-1;i++){
if(a[i]>a[i+1]){
sum+=(a[i]-a[i+1]);
a[i+1]=a[i];
}
}
cout<<sum<<'\n';
return 0;
}
把你切成L個部分,每個部份分別是a1,a2,a3,...,aN。
當你身體有x單位的身體被切割,身體會感受到x單位的痛苦。
那麼,要達成題目所指定的要求所需最少的痛苦度是多少?
我才沒有直接抄題目的舉例ㄋ
假設你的身體總共10單位,要分成2,2,3,3?
+4
+6
+10
分割ㄉ狀態 |
---|
{10} |
{4,6} |
{3,3,4} |
{2,2,3,3} |
分割ㄉ狀態 |
---|
{10} |
{2,8} |
{2,2,6} |
{2,2,3,3} |
+6
+8
+10
+4
+6
+10
+6
+8
+10
P =
4
+6
+10
P =
6
+8
+10
沒有錯,加回去的時候,每次都把最小的兩個元素加起來,最後痛苦度就會是最小的囉
假設要分成的單位是a1,a2,a3,...,aN,
其中 a1≤a2≤a3≤...≤aN
而每次切割所增加的痛苦度是pi,
痛苦度P=p1+p2+...+p(N-1)
那麼,只要將每次的pi都最小化,
我們就可以得到最少的痛苦度了呢
#include<iostream>
#include<queue>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
priority_queue<long long int, vector<long long int>, greater<long long int> > pq;
int n;
while(cin>>n){
int a;
long long int sum=0;
for(int i=1;i<=n;i++){
cin>>a;
pq.push(a);
}
for(int i=1;i<=n-2;i++){
long long int b=pq.top();pq.pop();
long long int c=pq.top();pq.pop();
pq.push(b+c);sum+=b+c;
}
sum+=pq.top();pq.pop();sum+=pq.top();pq.pop();
cout<<sum<<"\n";
}
return 0;
}
By liftleaf