洛谷
题意:
n
a1 a2 a3 …an
每次可以选择连续的一段区间,区间内的数都加1,询问至少多少次,能够将n 个0,转化成 给出的序列。
做题的时候没想到这个贪心。只想到了分治的思路。
思路:
将区间化划分成 若干不降区间(贪心的操作,确保每个不降区间尽可能的大)
2 3 4 /1 2
我们可以发现,
如果右边比左边低,那么在操作左边的时候,右边的已经满足了
如果右边比左边高,那么必须 额外的操作上 两者的差值。
#include <bits/stdc++.h>
using namespace std;
int main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int n; cin>>n;
vector<int>a(n);
for(int i=0;i<n;i++)
cin>>a[i];
int ans=a[0];
for (int i=1;i<n;i++)
{
ans+=max(0,a[i]-a[i-1]);
}
cout<<ans<<"\n";
return 0;
}
国王游戏
感性的思考一下:
要使最大值最小,(咋一听,有点二分的感觉,但实际上是贪心)要使得最大值最小,也就是削弱每位大臣的奖励。
因为左手上的数都是大于等于1的,所以 越到 后面,积越大。同时 越排在前面,左手数值产生的影响就越大。所以 我们可以粗略的感知到,左手数值小的在前面。
我们现在看右手数值,因为左右的累积是越来越大的,所以应该将右手数值大的放后面,换言之,右手数值小的在前面。
综上,看完题目,我们可以隐隐感觉出来,左右手小的排在前面。那么严谨点的排序依据什么(和?乘积?)
我们来研究 相邻 的两个数
综上可以看出来,我们应该按照 左右手乘积的方式排序。
之后 再配合 一点点 的高精度,既可以 愉快的把这道题 ac过去了。
#include <bits/stdc++.h>
using namespace std;
// 主要的思路:
//根据我们推导出来的,排序之后
//计算每一个大臣的奖励,找到其中的最大值
//输出答案
//其中 包含 高精度*低精度 高精度/低精度
// 乘积最大是 10000^1000
// 也就是 10^4000 也就是 4000位
struct node
{
int a,b;
bool operator <(node &t){
return a*b<t.a*t.b;
}
}p[1005] ;//最多有 1e3个
int m[4005],a[4005],t[4005];
//m 存储乘积,a存答案
int lm,la,lt;
void div(int *m,int b,int *t)
{
for (int i=1;i<=lt;i++)t[i]=0;
int r=0;
for (int i=lm;i>=1;i--){
r=r*10+m[i];
t[i]=r/b;
r%=b;
}
lt=lm;
while(t[lt]==0&<>1)lt--;
}
void mul(int *m,int b,int *t)
{
for (int i=1;i<=lt;i++)t[i]=0;
for (int i=1;i<=lm;i++)t[i]+=m[i]*b;
lm+=4;
for (int i=1;i<lm;i++)
{t[i+1]+=t[i]/10;
t[i]%=10;
}
while(t[lm]==0&&lm>1)lm--;
for (int i=1;i<=lm;i++)
m[i]=t[i];
}
bool cmp(int *a,int *t)
{
if (la!=lt) return la<lt;
for(int i=lt;i;i--)
{
if (a[i]!=t[i])
return a[i]<t[i];
}
return false;//相等的情况
}
void upd(int *a,int *t)
{
if (cmp(a,t)){
//如果 a<t,更新答案
for (int i=lt;i;i--)a[i]=t[i];
la=lt;
}
}
int main()
{
int n;cin>>n;
for (int i=0;i<=n;i++){
cin>>p[i].a>>p[i].b;
}
sort(p+1,p+n+1);
m[++lm]=p[0].a;//从1 开始存储
for (int i=1;i<=n;i++){
div(m,p[i].b,t);//将结果存储在t数组中
upd(a,t);
mul(m,p[i].a,t);
}
for (int i=la;i;i--)cout<<a[i];
return 0;
}
添加链接描述
这道题:
直觉上 应该把 重的力量大的放在下面。
我们可以猜测 按照 重量+力量 来排序。
贪心的证明:每一步都是最优的,那么全局最优
#include <bits/stdc++.h>
using namespace std;
bool cmp(pair<int,int>&a,pair<int,int>&b)
{
return a.first+a.second<b.first+b.second;
}
int main()
{
std::cin.tie(nullptr)->sync_with_stdio(false);
int n;cin>>n;
vector<pair<int,int>>ve(n);
for (int i=0;i<n;i++)
{
cin>>ve[i].first>>ve[i].second;
}
sort(ve.begin(),ve.end(),cmp);
int ans=-2e9;int sum=0;
for (int i=0;i<n;i++)
{
ans=max(ans,sum-ve[i].second);
sum+=ve[i].first;
}
cout<<ans<<"\n";
return 0;
}