牛客小白月賽100 ACM中的CM題

Coder何發表於2024-09-06

示例1

3
1 1 2

輸出

2
說明
瞬移到1處排 [1, 1]的2個雷
瞬移到2處排 [2, 2]的1個雷
示例2
4
1 2 4 5

輸出

3

首先嚐試了暴力解法,結果當然超時了。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 bool graph[200005];
 4 int n;
 5 int position = 0;
 6 int result = 10000;
 7 void travel(int index,int m,int count){
 8     if (position < index){
 9         result = min(count, result);
10         return;
11     }
12     int i;
13     for (i = index; i <= position; ++i){
14         if (graph[i]){
15             break;
16         }
17     }
18     if(m + 1 <= position - i)
19         travel(i, m + 1, count + 1);
20     travel(i + m, m, count + 1);
21 }
22 int main(){
23     cin>>n;
24     int temp;
25     memset(graph,false,sizeof(graph));
26     for (int i = 0; i < n; ++i){
27         cin>>temp;
28         graph[temp] = true;
29         position = max(position, temp);
30     }
31     
32     travel(1, 1, 0);
33     cout<<result<<endl;
34 }

然後試了dp,還是沒透過,看了唯一的題解,也沒看懂是不是貪心。‘

其思路是取 0<=m<=n,列舉後輸出最小花費。即固定m,然後看需要幾跳可以遍歷數軸。應該勉強算貪心策略吧....

#include<bits/stdc++.h>
using namespace std;
bool graph[200005];
int n;
int position = 0;
int result = INT32_MAX;
int travel(int index, int m, int count){
    if (position < index){
        return count;
    }
    int i;
    for (i = index; i <= position; ++i){
        if (graph[i]){
            break;
        }
    }
    return travel(i + m + 1, m, count + 1);
}
int main(){
    cin>>n;
    int temp;
    memset(graph, false, sizeof(graph));
    for (int i = 0; i < n; ++i){
        cin>>temp;
        graph[temp] = true;
        position = max(position, temp);
    }
    for (int i = 0; i <= n ; ++i){
        result = min(result,travel(1, i, i));
    }

    cout<<result<<endl;
}