【发布时间】:2020-03-09 07:06:31
【问题描述】:
在数轴上的不同位置有 n 个信标。第 i 个信标具有位置 ai 和功率电平 bi。当第 i 个信标被激活时,它会破坏其左侧(坐标递减方向)在距离 bi 内的所有信标。然而,信标本身并没有被破坏。埼玉将从右到左一次激活一个信标。如果信标被摧毁,则无法激活。
埼玉希望杰诺斯在所有现有信标的右侧添加一个严格的信标,具有任何位置和任何功率级别,以便尽可能少地破坏信标。请注意,Genos 放置信标意味着它将是第一个激活的信标。帮助 Genos 找出可以被摧毁的最小信标数量。
这里是问题的链接 (http://codeforces.com/contest/607/problem/A)
Screenshot of question.
我的方法是使用 Dp 查找未销毁的最小对象数。如果我只有 i 个元素,则 dp[i]= 未销毁的最小对象数。
- 当第 i 个对象被右侧的某个元素破坏时,让 inc 是答案。因此
inc = 1 + dp[i-1]
- 当第 i 个对象没有被右侧的某个元素破坏时,让 exc 为答案。由于第 i 个元素没有被破坏,所以当我们引爆它时,它会破坏其左边界(a[i]-b[i])内的所有元素。假设它可以破坏左侧的 lbd 个元素。因此 exc = lbd + dp[i-lbd]。
现在 dp[i] = min{ inc , exc }。最后返回 dp[n]。
但是我的代码在测试用例 11 中给出了错误的答案。如果我的逻辑或代码有问题,谁能帮助我?
这是我的代码 sn-p
ll = long long int
pll = 一对长整数
rep(i,0,n) = 从 0 到 n 的循环
void solve(){
ll n;
cin>>n;
vector<pll> a(n);
vector<ll> b(n);
rep(i,0,n){
cin>>a[i].first>>a[i].second;
b[i]=a[i].first;
}
sort(b.begin(),b.end());
sort(a.begin(),a.end(),cmp);
vector<ll> dp(n+1,0);
rep(i,1,n+1){
ll inc = 1+ dp[i-1];
ll temp = a[i-1].first-a[i-1].second;
ll lb = lower_bound(b.begin(),b.end(),temp)-b.begin();
ll exc=(i-lb-1)+dp[lb];
dp[i]=min(inc,exc);
}
cout<<dp[n]<<endl;
}
【问题讨论】:
-
b[i]=a[i].first;似乎很可疑。你真的需要b向量吗? -
不,我不需要 b[i],我只是使用 b[i] 以便可以在 b 上使用 lower_bound,否则,我必须编写一些额外的代码以便我可以在 a 上使用 lower_bound(它是对的向量)。
-
我认为您将我的 b 与问题中提到的功率级别 b[i] (等于 a[i].second )混淆了。我的“b”向量以递增顺序指示信标的位置。抱歉,我在命名变量时应该小心。我的逻辑需要找到直到信标可以摧毁其他信标的位置。 @JanezKuhar
-
感谢您的解决方案。我得到了你的方法。但我只是好奇为什么我的方法不起作用。
-
我已经用另一个解决方案(解决方案 #1)更新了我的答案。是否更清楚为什么您的方法不起作用?
标签: data-structures c++14 dynamic-programming