1. 会场安排问题--贪心
问题描述:
假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。)
编程任务:
对于给定的k 个待安排的活动,编程计算使用最少会场的时间表。
数据输入:
由文件input.txt 给出输入数据。第一行有1 个正整数k,表示有k 个待安排的活动。接下来的k 行中,每行有2 个正整数,分别表示k 个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。
结果输出:
将编程计算出的最少会场数输出到文件output.txt 。
输入文件示例输出文件示例
input.txt output.txt
5 3
1 23
12 28
25 35
27 80
36 50
#include<bits/stdc++.h>
using namespace std;
int k,ans,a[1010];
struct pd
{
int s,e;
}p[1010];
/*
5
1 23
12 28
25 35
27 80
36 50
*/
bool cmp1(pd a,pd b)
{
if(a.s==b.s)
return a.e<b.e;
else
return a.s<b.s;
}
int main()
{
cin>>k;
for(int i=1;i<=k;i++)
{
cin>>p[i].s>>p[i].e;
}
sort(p+1,p+k+1,cmp1);
for(int i=1;i<=k;i++)
{
int temp=ans;
for(int j=0;j<=temp;j++)//依次看几个组中可以融入
{
if(p[i].s>=a[j])
{
if(a[j]==0)
{
ans++;
}
a[j]=p[i].e;
break;
}
}
}
cout << ans;
return 0;
}
2. 硬币找钱问题--贪心
问题描述:
设有6 种不同面值的硬币,各硬币的面值分别为5 分,1 角,2 角,5 角,1 元,2 元。现要用这些面值的硬币来购物和找钱。购物时可以使用的各种面值的硬币个数存于数组Coins[1:6 ]中,商店里各面值的硬币有足够多。在1 次购物中希望使用最少硬币个数。
例如,1 次购物需要付款0.55 元,没有5 角的硬币,只好用2*20+10+5 共4 枚硬币来付款。如果付出1 元,找回4 角5 分,同样需要4 枚硬币。但是如果付出1.05 元(1 枚1 元和1 枚5 分),找回5 角,只需要3 枚硬币。这个方案用的硬币个数最少。
编程任务:
对于给定的各种面值的硬币个数和付款金额,编程计算使用硬币个数最少的交易方案。
数据输入:
由文件input.txt 给出输入数据。每一行有6 个整数和1 个有2 位小数的实数。分别表示
可以使用的各种面值的硬币个数和付款金额。文件以6 个0 结束。
结果输出:
将编程计算出的最少硬币个数输出到文件output.txt 。结果应分行输出,每行一个数据。如果不可能完成交易,则输出”impossible”。
输入文件示例
input.txt
2 4 2 2 1 0 0.95
2 4 2 0 1 0 0.55
0 0 0 0 0 0
输出文件示例
output.txt
2
3
#include<bits/stdc++.h>
using namespace std;
/*
2 4 2 2 1 0 0.95
2 4 2 0 1 0 0.55
0 0 0 0 0 0
*/
int coins[6],num=0,pay;
int v[6]={5,10,20,50,100,200};
int z[7] ={0,5,10,20,50,100,200};
int money=v[0]-z[0]; //实际支付=支付-找零
int contains(int a)
{
for(int i=0;i<6;i++)
{
if(v[i]==a && coins[i]>0)
return i;
}
return -1;
}
void guo()
{
for(int i=5;i>=0;i--)
{
if(coins[i]>0)
{
for(int j=0;j<=i;j++)
{
money=v[i]-z[j];
if(pay>=money)
{
if(coins[i]>=pay/money)
{
int temp=pay/money;
num+=temp*2;
if(contains(money)!=-1)
{
temp=min(temp,coins[contains(money)]);
num-=temp;
coins[contains(money)]-=temp;
}
else
coins[i]-=pay/money;
pay=pay%money;
if(contains(v[i])==-1)
break;
}
else
{
num+=coins[i];
pay=pay-v[i]*coins[i];
coins[i]=0;
}
}
}
}
}
}
int main()
{
while(1)
{
num=0;
int flag=0;
for(int i=0;i<6;i++)
{
cin >> coins[i];
if(coins[i]!=0)
{
flag=1;
}
}
if(flag==0)
{
return 0;
}
double t;
cin >>t;
pay=(int)(t*100);
guo();
if(num==0 || pay!=0)
{
cout <<"impossible\n";
}
else
{
cout <<num<<endl;
}
}
}
3. 汽车加油问题---贪心
问题描述:
一辆汽车加满油后可行驶n 公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。
编程任务:
对于给定的n 和k 个加油站位置,编程计算最少加油次数。
数据输入:
由文件input.txt 给出输入数据。第一行有2 个正整数n 和k,表示汽车加满油后可行驶n 公里,且旅途中有k 个加油站。接下来的1 行中,有k+1 个整数,表示第k 个加油站与第k-1 个加油站之间的距离。第0 个加油站表示出发地,汽车已加满油。第k+1 个加油站表示目的地。
结果输出:
将编程计算出的最少加油次数输出到文件output.txt 。如果无法到达目的地,则输出”No Solution”。
输入文件示例输出文件示例
input.txt
7 7
1 2 3 4 5 1 6 6
output.txt
4
#include<bits/stdc++.h>
using namespace std;
/*
7 7
1 2 3 4 5 1 6 6
*/
int n,k,a[1010],ans;
int main()
{
cin>>n>>k;
int flag=0;
for(int i=1;i<=k+1;i++)
{
cin>>a[i];
if(a[i]>n)
flag=1;
}
if(flag==1)
{
cout << "No Solution";
return 0;
}
int temp=n;
for(int i=1;i<=k+1;i++)
{
temp=temp-a[i];
if(temp-a[i+1]<0)
{
ans++;
//cout << i<<endl;
temp=n;
}
}
cout << ans;
return 0;
}
4. 最优分解问题--贪心
问题描述:
设n 是一个正整数。现在要求将n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。
编程任务:
对于给定的正整数n,编程计算最优分解方案。
数据输入:
由文件input.txt 提供输入数据。文件的第1 行是正整数n。
结果输出:
程序运行结束时,将计算出的最大乘积输出到文件output.txt 中。
输入文件示例
input.txt
10
输出文件示例
output.txt
30
#include<bits/stdc++.h>
using namespace std;
int n,ans=1,a[1010]={0};
int main()
{
cin>>n;
int i=1,j;
a[0]=1;
while(n>a[i-1]) //最初分配的因子
{
a[i]=a[i-1]+1;
n-=a[i];
i++;
}
while(n>0) //剩下的数依次减一,加在已分配好的因子上
{
for(j=1;j<i;j++)
{
a[i-j]++;
n--;
if((i-j)==0)
{
j=1;
break;
}
if(n==0)
break;
}
}
for(j=1;j<i;j++)
{
ans=ans*a[j];
}
cout << ans;
return 0;
}
5. 程序存储问题----贪心算法
问题描述:
设有n 个程序{1,2,…, n }要存放在长度为L 的磁带上。程序i 存放在磁带上的长度是li,1≤i≤n 。程序存储问题要求确定这n 个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。
编程任务:
对于给定的n 个程序存放在磁带上的长度,编程计算磁带上最多可以存储的程序数。
数据输入:
由文件input.txt 给出输入数据。第一行是2 个正整数,分别表示文件个数n 和磁带的长度L。接下来的1 行中,有n 个正整数,表示程序存放在磁带上的长度。
结果输出:
将编程计算出的最多可以存储的程序数输出到文件output.txt 。
输入文件示例输出文件示例
input.txt
6 50
2 3 13 8 80 20
output.txt
5
#include<bits/stdc++.h>
using namespace std;
int n,l,a[1010],ans;
/*
6 50
2 3 13 8 80 20
*/
int main()
{
cin>>n>>l;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
sort(a+1,a+n+1);
for(int i=1;i<=n;i++)
{
if(l-a[i]>0)
{
l-=a[i];
ans++;
}
}
cout << ans;
return 0;
}