田忌賽馬 泡泡堂

2022-05-08 06:15:13 字數 3368 閱讀 2471

from 黃學長

本題原來是用貪心的思路,用田忌速度從小到大的每一匹馬去戰勝或打平齊王的最強的馬

像這樣

1 #include2 #include3

using

namespace

std;

4int

main()

5,tj[10001]=;

7int

n;8 cin>>n;

9long

long ans=-n*200;10

for(int i=1;i<=n;i++)

11 cin>>tj[i];

12for(int i=1;i<=n;i++)

13 cin>>qw[i];

14 sort(tj,tj+n+1

);15 sort(qw,qw+n+1

);16

for(int i=1;i<=n;i++)

1721

else

if(tj[i]==qw[j])22}

23}24 cout<0

,ans);

25 system("

pause");

26return0;

27 }

是有反例的,因為看不符合歷史上賽馬的典故,用這種方法下等馬變成和下等馬賽平了,顯然不妥。

但是用最弱的馬故意輸最強的馬當然也是不可取的。

網上有種貪心做法是這樣

1 #include 2 #include 3 #include 4

using

namespace

std;

5const

int max=10000;6

inttian[max],king[max];

7int

i,j,n;

8bool cmp(int a,int b)

9int

main()

1013

for(i=1;i<=n;i++)

14 sort(tian+1,tian+1+n,cmp);

15 sort(king+1,king+1+n,cmp);

16int ans=0;17

intii,jj;

18for(i=1,j=1,ii=n,jj=n;i<=ii;)

1921

else

if(tian[i]200;j++,ii--;}

22else

2329

else

3035}36

}37 cout<38return0;

39 }

1、開始也是先排序,可以使用sort快排;

2、然後將田忌最大的馬與國王進行比較;

3、如果田忌最大的馬大於國王,那麼就勝場++;

4、如果田忌最大的馬小於國王,那麼就一定會輸,所以用田忌最小的馬輸給國王最大的馬;

5、如果田忌最大的馬等於國王,那麼就比較最小的馬;

5。1、如果田忌最小的馬大於國王,那麼勝場++;

5。2、如果田忌最小的馬小於國王,那麼就輸給國王;

5。3、如果田忌最小的馬等於國王,就用田忌最小的馬對國王最大的馬,如果國王最大的馬大,那麼財產要減200;

還有動規的

1.思路

不妨用貪心思想來分析一下問題。因為田忌掌握有比賽的「主動權」,他總是根據齊王所出的馬來分配自己的馬,所以這裡不妨認為齊王的出馬順序是按馬的速度從高到低出的。由這樣的假設,我們歸納出如下貪心策略:

如果田忌剩下的馬中最強的馬都贏不了齊王剩下的最強的馬,那麼應該用最差的一匹馬去輸給齊王最強的馬。

如果田忌剩下的馬中最強的馬可以贏齊王剩下的最強的馬,那就用這匹馬去贏齊王剩下的最強的馬。

如果田忌剩下的馬中最強的馬和齊王剩下的最強的馬打平的話,可以選擇打平或者用最差的馬輸掉比賽。

2.反例

光是打平的話,如果齊王馬的速度分別是1 2 3,田忌馬的速度也是1 2 3,每次選擇打平的話,田忌一分錢也得不到,而如果選擇先用速度為1的馬輸給速度為3的馬的話,可以贏得200兩**。

光是輸掉的話,如果齊王馬的速度分別是1 3,田忌馬的速度分別是2 3,田忌一勝一負,仍然一分錢也拿不到。而如果先用速度為3的馬去打平的話,可以贏得200兩**。

3.解決方案

通過上述的三種貪心策略,我們可以發現,如果齊王的馬是按速度排序之後,從高到低被派出的話,田忌一定是將他馬按速度排序之後,從兩頭取馬去和齊王的馬比賽。有了這個資訊之後,動態規劃的模型也就出來了!

4.dp方程

設f[i,j]表示齊王按從強到弱的順序出馬和田忌進行了i場比賽之後,從「頭」取了j匹較強的馬,從「尾」取了i-j匹較弱的馬,所能夠得到的最大盈利。

狀態轉移方程如下:

f[i,j]=max

其中g[i,j]表示田忌的馬和齊王的馬分別按照由強到弱的順序排序之後,田忌的第i匹馬和齊王的第j匹馬賽跑所能取得的盈利,勝為1,輸為-1,平為0。

結果用最大的乘以200即可。

5.解釋

為什麼f[i,j]=max可以呢?

因為你無論怎麼樣都是從前或者從後面取馬,而f[i,j]=max這個方程把所有可能的貪心情況都表示出來了。

1 #include2 #include3 #include4

using

namespace

std;

5int f[3001][3001],a[3001],b[3001],c[3001][3001];6

int n,ans=0;7

bool gz(int a,int b)

8int

main()

9

泡泡堂

1 #include2 #include3 #include4

using

namespace

std;

5const

int maxn=1e7+7;6

intn,l1,r1,l2,r2,ret;

7int

a[maxn],b[maxn];

8bool cmp(int a,int b)

9int proc(int *a,int *b)

15else

19else

23 l1++;r2--;24}

25}26}

27return

ret;28}

29int

main()

這裡面有乙個小小的轉化,要靈活

大概就是無論從小到大排還是從大到小排都行,但有一點不太一樣

假設是從小到大排序:

每次都應該選最小的比它大的,但是,因為是已經排好序的,所以不必每局或者二分,直接挨個跳就行了,無論是從前計算還是從後計算都是這樣

到了here的時候,如果a[r1]

BZOJ1034泡泡堂 貪心(田忌賽馬)

第一想法肯定就是田忌賽馬然後想起老闆原來講的二分圖。後來發現田忌賽馬原來有個很顯然地貪心做法 模擬原場景 time limit 10 sec memory limit 162 mb submit 3840 solved 1973 submit status discuss 第 x屆noi期間,為了加...

cocos泡泡堂要點

cc是全域性的東西 1 挪資源要在編輯器裡面挪,裡面的東西改變會自動更新,裡面有很多的meta檔案記錄很多資訊,uid等,meta檔案也不能刪。在外面挪資源的話可能會改變它的資訊讓編輯器識別不出來。2 資料夾管理,對資源進行歸類。3 節點下面有 1 指令碼元件 2 內建元件 3 預製元件 cc.in...

BZOJ1034 泡泡堂(貪心)

bzoj 洛谷很基礎的貪心,然而我竟然沒寫對。身敗名裂。大概就是類似田忌賽馬。先拿看當前最大值是否能否解決對面最大值,否則檢查能否用最小值來兌掉。差不多類似把,有點點區別。include include include include include include using namespace ...