烽火台又称烽燧,是重要的军事防御设施,一般建在险要处或交通要道上。一旦有敌情发生,白天燃烧柴草,通过浓烟表达信息;夜晚燃烧干柴,以火光传递军情。在某两座城市之间有n个烽火台,每个烽火台发出信号都有一定的代价。为了使情报准确地传递,在连续的m个烽火台中至少要有一个发出信号。现输入n、m和每个烽火台发出信号的代价,请计算总共最少花费多少代价,才能使敌军来袭之时,情报能在这两座城市之间准确传递。
例如,有5个烽火台,他们发出信号的代价依次为1,2,5,6,2,且m为3,则总共最少花费代价为4,即由第2个和第5个烽火台发出信号。
#include<iostream> #include<cstring> using namespace std; const int SIZE=100; int n,m,r,value[SIZE],heap[SIZE],pos[SIZE],home[SIZE],opt[SIZE]; //hep[i]表示用顺序数组储存的堆heap中第i个元素的值 //pos[i]表示opt[i]在堆heap中的位置,即heap[pos[i]]=opt[i] //home[i]表示heap[i]在序列opt中的位置,即opt[home[i]]=heap[i] void swap(int i,int j)//交换堆中的第i个和第j个元素 { int tmp; pos[home[i]]=j; pos[home[j]]=i; tmp=heap[i]; heap[i]=heap[j]; heap[j]=tmp; tmp=home[i]; home[i]=home[j]; home[j]=tmp; } void add(int k)//在堆中插入opt[k] { int i; r++; heap[r]=______(1)________; pos[k]=r; ______(2)________; i=r; while( (i>1) && (heap[i]<heap[i/2]) ) { swap(i,i/2); i/=2; } } void remove(int k)//在堆中删除opt[k] { int i,j; i=pos[k]; swap(i,r);; r--; if(i==r+1) return ; while( (i>1)&&(heap[i]<heap[i/2]) ) { swap(i,i/2); i/=2; } while(i+i<=r) { if( (i+i+1<=r) && (heap[i+i+1]<heap[i+i]) ) j=i+i+1; else _____(3)_______; if(heap[i]>heap[j]) { _____(4)_______; i=j; } else break; } } int main() { int i; cin>>n>>m; for(i=1;i<=n;i++) cin>>value[i]; r=0; for(i=1;i<=m;i++) { opt[i]=value[i]; add(i); } for(i=m+1;i<=n;i++) { opt[i]=______(5)________; remove(_____(6)_________); add(i); } cout<<heap[1]<<endl; return 0; }