1.三值排序
贪心策略:统计1,2,3的个数
首先在根据统计的个数规定1,2,3的区间
首先,将1的区间内有3的个数时交换并统计
然后,再在1的区间内找2
最后,在2的区间内找3
奉上pascal代码:
program used_pascal;
var n:integer;
i,j,t,ans:longint;
a:array[-10..10000] of longint;
b:array[-10..10000] of longint;
begin
read(n);
for i:=1 to n do
read(a[i]);
for i:=1 to n do
inc(b[a[i]]);
for i:=1 to b[1] do
begin
if a[i]=3 then
begin
for j:=n downto b[1]+1 do
if a[j]=1 then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(ans);
break;
end;
end;
if a[i]=2 then
begin
for j:=b[1]+1 to n do
if a[j]=1 then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(ans);
break;
end;
end;
end;
for i:=b[1]+1 to b[1]+b[2] do
if a[i]=3 then
begin
for j:=b[1]+b[2]+1 to n do
if a[j]=2 then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(ans);
break;
end;
end;
write(ans);
end.
2.修理牛棚
首先,排序
其次,按间隔排序,由题意可知要-1
最后根据排序结果累加
最后减一减即可
其贪心策略要求木材尽量小,间隔尽量大,自然要通过排序来解决,也就形成了这道题目的贪心策略
非主流代码如下(暴露真名惹):
#include
using namespace std;
inline bool ZhouYibo_2023_cmp (int x,int y){return x>y;
}
int main()
{
int h,s,c,k=0;
int a[10000]={};
cin>>h>>s>>c;
for (int i=1;i<=c;i++)
cin>>a[i];
sort(a+1,a+c+1);
int b[10000]={};
for (int i=1;i<c;i++)
b[i]=a[i+1]-a[i]-1;
sort(b+1,b+c,ZhouYibo_2023_cmp);
for (int i=1;i<=h-1;i++)
k+=b[i]; cout<<a[c]-a[1]+1-k;
}
3.游荡的奶牛
为了使线段后后面部分产生影响,按照右端点
又因为为了使尽量挑长度小的覆盖,所以相同右端点时起点靠右边的在前面
//贪心策略:按右端点排序,防止最右边产生影响
#include
struct AC{
int left,right;
}Line[100000]={};
inline bool cmp(AC x,AC y){return x.right<y.right;}
int n;
using namespace std;
int main()
{
cin>>n;
for (int i=1;i<=n;i++)
cin>>Line[i].left>>Line[i].right;
sort(Line+1,Line+n+1,cmp);
int now=1,ans=1;
for (int i=1;i<=n;i+=1)
{
if (Line[now].right<=Line[i].left)
now=i,
ans++;
}
cout<<ans;
return 0;
}
4.游荡的奶牛
同样,只要变换一下判断条件,即if语句
原来是:判断这条线所放的地方有没有被放过
现在是:判断这条线所能放的每一个地方被放过的次数是否都
#include
struct AC{
int left,right;
}Line[100000]={};
inline bool cmp(AC x,AC y){return x.right<y.right ||( (x.right==y.right&&x.left>=y.left) ); }
int n,k;
int num[100000]={};
int answer=0;
using namespace std;
int main()
{
cin>>n>>k;
for (int i=1;i<=n;i++)
{
int A,C,B;
cin>>A>>C>>B>>C;
Line[i].left=min(A,B);
Line[i].right=max(A,B);
}
sort(Line+1,Line+n+1,cmp);
for (int i=1;i<=n;i++)
{
int flag=0;
for (int Check=Line[i].left;Check<=Line[i].right;Check++)
if (num[Check]>=k)
{
flag=1;
break;
}
if (flag==1) continue;
for (int Now=Line[i].left;Now<=Line[i].right;Now++)
num[Now]++;
answer++;
}
cout<<n-answer;
return 0;
}
5.删数问题
....未完待续