基礎演算法:貪心(待整理)
阿新 • • 發佈:2020-08-13
貪心演算法的定義與性質:
-
貪心演算法是通過做出一系列 選擇 來求出問題的最優解。在每一個決策點,它作出在 當前看來最好 的選擇。
-
(也就是說貪心演算法並 不從整體最優上加以考慮 ,它所作出的選擇只是在某種意義上的 區域性最優選擇 。大概也是貪心演算法名字的由來)
-
(貪心演算法進行決策時, 可能依賴於以往所做出的選擇,但決不依賴於將來所做的選擇,或者子問題的解 。)
-
-
貪心演算法必須滿足 最優子結構 。與動態規劃不同,貪心的最優子結構,必須滿足 選擇後只留下一個子問題 。
-
(從最優子結構的角度說:相當於特殊的動態規劃。動態規劃的選擇後往往會產生多個子問題。)
-
(正是由於這種差異,動態規劃演算法通常以自底向上的方式解各子問題,而 貪心演算法則通過以自項向下的方式
-
-
貪心的正確性:必須滿足 貪心選擇 與 剩餘相容活動集 的最優解,組合在一起後,就會得到原問題的最優解。
PS:可以設計一個遞迴演算法實現貪心策略,再將遞迴演算法轉化為迭代演算法。因為迭代的效率更高。
PS:若在進行貪心選擇中,不得不考慮列舉眾多選擇來找到最優,通常意味著可以改進貪心選擇,使其更高效。通常的改進辦法是:使用 合適的資料結構 或 預處理 。
打水問題:
刪數問題:
#include<bits/stdc++.h> #define MAXN 10000 using namespace std; int main() { string s; int len,k; cin>>s>>k; len=s.size(); for(int t=1;t<=k;++t) { for(int i=0;i<len;++i) { if(s[i]>s[i+1]) { for(int j=i;j<len;++j) s[j]=s[j+1]; --len; break; } } } int i; for(i=0; s[i]=='0' ;++i); if(i==len) cout<<"0"; else { for(;i<len;++i) cout<<s[i]; } return 0; }
僱傭計劃:
#include <bits/stdc++.h> using namespace std; int ned[100]; int main() { int n,a,b,c,more; int choice1,choice2,k; scanf("%d%d%d%d",&n,&a,&b,&c); for(int i=1;i<=n;++i) scanf("%d",&ned[i]); int ans=(a+b)*ned[1]; for (int i=2;i<=n;++i) { ans+=b*ned[i],more=ned[i]-ned[i-1]; if(more>=0) ans+=a*more; else { more=abs(more); for (int j=1;j<=more;++j) { choice1=0; for (k=i+1;k<=n;++k) if (ned[k]>ned[i]) {choice1=a;break;} choice1+=c;//dismiss choice2=b*(k-i);//employ if (choice1>=choice2) ++ned[i],ans+=b; else {ans+=c*(more-j+1);break;} } } } printf("%d\n",ans); return 0; }
拔河:
三國遊戲: