1.删数
一道不算太难的贪心,但是还是有值得注意的地方,首先贪心并不是去贪数串中最大的,将其删掉。如果这么做,就相当于用贪心做dp题,只是局部最优并不是全局最优。手打几个样例不难发现我们只需要将比它后一位大的数删掉即可保证最优解。然后贪心就迎刃而解。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
char c[257];
int main() {
int len,i,j,s;
scanf("%s%d",c,&s);
len=strlen(c);
while(s--) {
for(i=0; i<=len-2; i++)
if(c[i]>c[i+1]) {
for(j=i; j<=len-2; j++)
c[j]=c[j+1];
break;
}
len--;
}
i=0;
while(i<=len-1&&c[i]=='0') i++;//处理前导0
if(i==len) {
printf("0");
} else {
for(j=i; j<=len-1; j++) {
printf("%c",c[j]);
}
}
return 0;
}
2.国王的游戏
跟奶牛玩杂技几乎一样,只需要按照左手与右手数乘积之和进行排序即可,注:运算时要用高精。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
inline int read() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int n,l1,l2;//l1为前i个数a的和的长度,l2为最大值的长度。
int b[10005],c[10005],d[10005];//因为数据过大,开了一万的数组。
struct node {
int a,b,c;
} a[1005];
int cmp(node x,node y) {
if(x.c!=y.c) {
return x.c<y.c;
} else { //在a*b相同的情况下,a小的放在前面。
return x.a<y.a;
}
}
int hpm(node t) { //高精度的乘法(模拟大数乘小数)
int i,x=0,h=0;//x为进位数
for(i=1; i<=l1; i++) {
b[i]*=t.a;
}
for(i=1; i<=l1; i++) { //对大于10的数据取模
h=x;
x=(b[i]+x)/10;
b[i]=(b[i]+h)%10;
}
while(x!=0) { //进制位不为0(相乘后超出了l1)
b[++l1]=x%10;
x/=10;
}
}
int hpr(node t) { //高精除法
int x=0,l=0;
for(int j=l1; j>=1; j--) {
x=x*10+b[j];
if(j>l)l=j;//除数的长度
d[j]=x/t.b;
x%=t.b;
}
if(l>l2) { //除数长度大于最大数的长度直接更新
l2=l;
for(int i=1; i<=l; i++) {
c[i]=d[i];
}
} else if(l==l2&&l!=0) {
int flag=0;
for(int i=l; i>=1; i--) {
if(d[i]>c[i]) { //当除数大于最大数更新
for(i=1; i<=l; i++) {
c[i]=d[i];
}
}
}
} else
return 0;//小于直接返回
}
int main() {
int i,j,k;
n=read();
for(i=0; i<=n; i++) {
a[i].a=read(),a[i].b=read();//输入左手和右手上数
a[i].c=a[i].a*a[i].b;
}
k=0;
while(a[0].a!=0) { //把国王右手上的数,放入b数组
b[++k]=a[0].a%10;
a[0].a/=10;
l1++;
}
sort(a+1,a+n+1,cmp);//对大臣左右手的乘积排序
for(i=1; i<=n; i++) {
hpr(a[i]);
hpm(a[i]);
}
while(c[l2]==0) l2--;//删除前导0
for(j=l2; j>=1; j--) { //逆序输出
printf("%d",c[j]);
}
return 0;
}
3.修理牛棚
又是贪心(老贪官了),只需将牛的位置进行加减,不是相邻的牛只需一个板,然后在排序一下即可得出答案。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
const int maxn = 307;
using namespace std;
inline int read() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
int m,s,c,ans;
int a[maxn],c1[maxn];
bool cmp(int x,int y){
return x>y;
}
int main() {
m=read(),s=read(),c=read();
for(int i=1;i<=c;i++)
a[i]=read();
if(m>c) {
printf("%d
",c);
return 0;
}
sort(a+1,a+c+1);
ans=a[c]-a[1]+1;
for(int i=2;i<=c;i++){
c1[i-1]=a[i]-a[i-1];
}
sort(c1+1,c1+c,cmp);
for(int i=1;i<=m-1;i++){
ans=ans-c1[i]+1;
}
printf("%d
",ans);
}
4.机器工厂/奶酪工厂
一道贪心的题,只需要边输入边比较即可得出最优的解,即完成贪心。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
inline long long read(){
long long x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
inline int read1() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
long long ans,sum,tmp,n,s,f;
int main(){
n=read(),s=read(),sum=read1(),tmp=read1();
ans+=sum*tmp;
f=sum;
for(int i=2;i<=n;i++){
sum=read1(),tmp=read1();
if(f+s<sum) f=f+s;
else f=sum;
ans+=f*tmp;
}
printf("%lld",ans);
return 0;
}
5.奶牛玩杂技
类似国王的游戏,只需将体重与力量乘积最大的放到下面,即可获得最优答案。
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
const int inf=0x3f3f3f3f;
using namespace std;
inline int read() {
int x=0,f=1;
char ch=getchar();
while(ch<'0'||ch>'9') {
if(ch=='-') f=-1;
ch=getchar();
}
while(ch>='0'&&ch<='9') {
x=(x<<1)+(x<<3)+(ch^48);
ch=getchar();
}
return x*f;
}
struct cow{
int w,s;
}c[50002];
long long ans=-inf,wt;
int n;
bool cmp(cow a,cow b){
return a.w+a.s<b.w+b.s;
}
int main(){
n=read();
for(int i=1; i<=n; i++){
c[i].w=read(),c[i].s=read();
wt+=c[i].w;
}
sort(c+1,c+n+1,cmp);
for(int i=n; i>=1; i--){
wt-=c[i].w;
ans=max(wt-c[i].s,ans);
}
printf("%lld",ans);
return 0;
}