貪心法-求解區間覆蓋問題
阿新 • • 發佈:2019-03-30
結果 i++ start tdi oid str std 我們 接下來
題目內容:
設x1,x2,... ,xn是實直線上的n個點。用固定長度的閉區間覆蓋這n個點,至少需要多少個這樣的固定長度閉區間?設計求解此問題的有效算法。對於給定的實直線上的n個點和閉區間的長度k,編程計算覆蓋點集的最少區間數。
輸入格式:
輸入數據的第一行有2個正整數n和k,表示有n個點,且固定長度閉區間的長度為k。接下來的1行中,有n個整數,表示n個點在實直線上的坐標(可能相同)。
輸出格式:
將編程計算出的最少區間數輸出。
個人分析如下:
由於這n個點的順序與程序輸入有關,因此我們需要將輸入的數字進行一次排序並存在一個數組中。由於我們只考慮局部最優解,因此可以從第一個點(即最小的點)開始插入閉區間,並排除所有在此區間的點。如此往復即可得到最終結果。
代碼如下:
1 #include<stdio.h> 2 void sort(int a[],int n); 3 int cover(int a[],int n,int k); 4 int main() 5 { 6 int n,k; 7 scanf("%d%d",&n,&k); 8 int a[100]; 9 for(int i=0;i<n;i++) 10 { 11 scanf("%d",&a[i]); 12 } 13 // sort(a,n);14 // for(int i=0;i<n;i++) 15 // { 16 // printf("%d ",a[i]); 17 // } 18 printf("%d",cover(a,n,k)); 19 return 0; 20 } 21 22 void sort(int a[],int n) 23 { 24 for(int i=0;i<n;i++) 25 { 26 int min=i; 27 for(int j=i+1;j<n;j++) 28 { 29 if(a[j]<a[min]) 30 min=j; 31 } 32 // printf("min = %d\n",min); 33 int temp=a[i]; 34 a[i]=a[min]; 35 a[min]=temp; 36 // printf("ai = %d\n",a[i]); 37 } 38 } 39 40 int cover(int a[],int n,int k) 41 { 42 sort(a,n); 43 int sum=0;//用於記錄區間個數 44 int t=0; //用於標記已被覆蓋的點序號 45 int start=0; 46 while(t<n) 47 { 48 printf("NO.%d: ",sum+1); 49 for(t;a[t]<=a[start]+k && t<n;t++) 50 { 51 printf("%d ",a[t]); 52 } 53 printf("\n"); 54 start=t; 55 sum++; 56 } 57 return sum; 58 }
運行結果如下:
輸入樣例: 7 3 1 2 3 4 5 -2 6 輸出樣例: NO.1: -2 1 NO.2: 2 3 4 5 NO.3: 6 3
貪心法-求解區間覆蓋問題