📅  最后修改于: 2023-12-03 15:12:45.800000             🧑  作者: Mango
这是2019年清华大学计算机系B类机试的编程题目之一,题号为“门|门 CS 1996 |第 51 题”。该题目有一定难度,需要有一定的算法基础和编程经验才能解决。
在一条直线上,有 n 个点(n<=1000),这些点从左到右标号为 0 ~ n-1,其中每个点都是响铃的门。现在需要修建补偿量等于 w 的办法。具体方法如下:
你需要设计一个方案,使得最小化支付的费用 total,使得 total<=2000000。
该题目是一道经典的贪心算法题目。我们可以借鉴哈夫曼编码的思想,从下到上依次构建控制器。首先需要对 n 个门按照初始状态(即未被控制前,门是否能从外部打开)进行排序,然后从n-1开始依次考虑,对于每个门i,如果它的状态是按在开着的,那么我们不需要为其建立控制器;如果它的状态是关着的,那么我们需要为其建立一个控制器,并将它的关状态转变为开。在具体实现该算法的过程中,可以使用一个布尔数组来记录每个门的状态,使用一个int数组记录每个门的代价。
#include<bits/stdc++.h>
using namespace std;
const int MAXN=1010;
int n,w;
int cost[MAXN];
bool door[MAXN];
int main(){
cin>>n>>w;
for(int i=0;i<n;i++){
char ch;
cin>>ch;
door[i]=(ch=='1');
}
int ans=0;
for(int i=0;i<n;i++){
if(i==0||door[i]){
ans+=cost[i];
}
else{
int need=i;
for(int j=0;j<=i;j++){
if(door[j]&&need<=w){
need=j;
break;
}
if(door[j]){
need=min(need,j-w);
}
else{
need=max(need,j+w);
}
}
if(need<=w) ans+=cost[i];
door[need]=true;
cost[need]=i+1;
}
}
cout<<ans<<endl;
return 0;
}
这是一道相对来说比较难的贪心算法题目。在实现过程中,需要设计合适的数据结构来记录每个门的状态和代价。同时,还需要根据具体的情况来合理地选取数据结构进行求解。