Title: BZOJ1150, codevs1615, Rokua P3620
Main topic: there are n points, K chain, each point from the origin of a certain distance. You use the K chain to connect 2k points, so that the length of the K-bar chain is the shortest.
Problem Solving ideas: After all, is the CTSC level of the topic, it is difficult to find the correct algorithm. After flipping through a lot of information on the Internet, I finally understood the correct algorithm of the problem. Orz
The correct algorithm is: Greedy + linked list + heap.
First of all must be the chain adjacent to the 2 points, so we first put the difference between the adjacent 2 points, to get the number of n-1.
The question then becomes "to look for K non-contiguous points in this sequence, making them and the smallest."
We throw all the numbers into a heap, and each time the greedy finds the smallest number, add it in the answer.
Then there is a problem: if we greedy out of the number of the first, then it is possible to select the number of i-1 and the number of i+1 the final result is better than the number of selected I.
So every time we greedy, we find the number of the previous number and the last number to delete, the "previous number + the next number-the original number" value thrown into the heap, if the number is selected, the equivalent of selecting the previous number and the next number without selecting the original number.
The linked list records the previous and the last of each number. See line 32nd to 35th of the code.
When you delete a number, you do not need to find the number in the heap, just change its value to INF. See line 36th of the code.
C + + Code:
#include <cstdio> #include <ext/pb_ds/priority_queue.hpp>const int inf=int (1000000000*1.3); using namespace std;struct shuju{int dis,num;shuju (int d,int N):d is (d), num (n) {}bool operator< (const shuju& RHS) const{ Return dis>rhs.dis;}}; __gnu_pbds::p riority_queue<shuju,less<shuju>,__gnu_pbds::p airing_heap_tag>h;int n,k,dis[100005],pre [100005],nxt[100005];int Main () {scanf ("%d%d", &n,&k); int x,y;scanf ("%d", &x); for (int i=2;i<=n;i++) { scanf ("%d", &y);d Is[i]=y-x;x=y;h.push (Shuju (dis[i],i));p re[i]=i-1;nxt[i]=i+1;} int Ans=0;pre[2]=nxt[n]=0;while (k--) {while (H.top (). Dis!=dis[h.top (). Num]) h.pop (); int k=h.top (). Num;int l=pre[k],r =nxt[k];h.pop (); ans+=dis[k];if (L&&r) dis[k]=dis[l]+dis[r]-dis[k];elsedis[k]=inf;pre[nxt[r]]=k;nxt[pre[l ]]=K;NXT[K]=NXT[R];p re[k]=pre[l];d is[l]=dis[r]=inf;h.push (Shuju (Dis[k],k));} printf ("%d\n", ans); return 0;}
[ctsc2007][apio2007] data back up backup