NOIP2009普及組 道路遊戲
阿新 • • 發佈:2019-01-10
Description
有一條環形路,路上有n個點,第i個點和第i+1個點有邊相連(第n個點與第1個點有邊相連)。每個點都可以花費不同的代價生產一個機 器人,且機器人可以順時針走不多於p步(每走一步消耗一單位時間),並撿起此時路上的
金幣。最多隻能有一個機器人存在於路上。不同的時間每條路上金幣數不 同。求最後能夠得到的最大金幣數(即
撿起的金幣數減去生產機器人需要的金幣數)。
Input
第一行3個正整數,n,m,p,意義如題目所述。接下來的n行,每行有m個正整數,每兩個整數之間用一個空格隔開,
其中第i行描述了i號馬路上每個單位時間內出現的金幣數量(1≤金幣數量≤1000),
即第i行的第j(1≤j≤m)個數表示第j個單位時間內i號馬路上出現的金幣數量。
最後一行,有n個整數,每兩個整數之間用一個空格隔開,
其中第i個數表示在i號機器人工廠購買機器人需要花費的金幣數量(1≤金幣數量≤1000)。
Output
包含 1 個整數,表示在 m 個單位時間內,扣除購買機器人花費的金幣之後,小新最多能收集到多少金幣。
Sample Input
2 3 2
1 2 3
2 3 4
1 2
Sample Output
5
實在是沒想到noip普及組會出這樣的題,我保證大多數人這道題寫的是dp,有O(N^3)和O(N^2)的,但是官方給的正解這道題卻是單調佇列
下面給大家解釋一下為什麼可以寫單調佇列:
首先,O(N^3)的寫法還是那麼腦殘(當然得不了滿分),列舉時間,位置,當前走的步數就解決了
其次,O(N^2)其實已經可以算是正解了,具體的我真的也不好講,這個都是從別人那裡得來的經驗
網址:http://blog.csdn.net/yuyanggo/article/details/48685873
我相信那個程式碼寫的很玄學,很難看懂,所以我就加入註釋,算是幫助大家啦(其實我也看了2天才差不多看懂,整整8個小時啊)
程式碼:
#include<cstdio> #include<algorithm> using namespace std; struct oo { int x,y; }q[1001][1001]; int n,m,p; int a[1001][1001],b[1001][1001],fm[1001],cost[1001]; void readdata() { int i,j,k; scanf("%d%d%d",&n,&m,&p); for(i=0;i<n;i++) for(j=1;j<=m;j++) scanf("%d",&b[i][j]);//讀入部分 for(i=0;i<n;i++)scanf("%d",&cost[i]); for(i=0;i<n;i++)a[1][i]=b[i][1];//a[1][i]代表第1個時間點在第i段路上能得到的金幣數 for(i=2;i<=m;i++) for(j=0;j<n;j++) a[i][j]=a[i-1][(j-1+n)%n]+b[j][i];//a[i][j]代表第i個時間點在第j段路上能得到的金幣數 , (j-1+n)%n這裡是在處理環 } void del(int t,int yy) { int i,j,k=q[t][0].x; for(i=k;q[t][i].y>0;i++) if(yy-q[t][i].y<p)break; q[t][0].x=i; } void add(int t,int yy,int xx) { int i,j,k=q[t][0].x; if(k==0)//假如當前佇列為空 { q[t][0].x=1; q[t][1].x=xx,q[t][1].y=yy; return; } for(i=k;q[t][i].y>0;i++) if(q[t][i].x<=xx)break;//維護佇列單調下降 q[t][i].x=xx,q[t][i].y=yy;//加入佇列 } void work() { int i,j,k,x; for(i=1;i<=m;i++) for(fm[i]=-1000000,j=0;j<n;j++) { k=(i-j+n)%n;//本程式碼的一個玄學點 /*仔細計算你會發現k的值是有規律的,當k相同時,上次的i和j和和這次的i和j肯定是可以轉移的*/ del(k,i);//有點不確定,但是應該是判斷當前機器人能走的點 add(k,i,fm[i-1]-a[i-1][(j-1+n)%n]-cost[j]);//入隊 x=a[i][j]+q[k][q[k][0].x].x;//當前能得到的最大價值 fm[i]=max(fm[i],x);//統計答案 } printf("%d",fm[m]); } int main() { readdata(); work(); }