算法实验复习四 贪心

会场安排问题

问题描述:

  假设要在足够多的会场里安排一批活动,并希望使用尽可能少的会场。设计一个有效的贪心算法进行安排。(这个问题实际上是著名的图着色问题。若将每一个活动作为图的一个顶点,不相容活动间用边相连。使相邻顶点着有不同颜色的最小着色数,相应于要找的最小会场数。)

编程任务:

  对于给定的k 个待安排的活动,编程计算使用最少会场的时间表。

数据输入:

  第一行有1 个正整数k,表示有k 个待安排的活动。接下来的k 行中,每行有2 个正整数,分别表示k 个待安排的活动开始时间和结束时间。时间以0 点开始的分钟计。

结果输出:

  输出最少会场数 。

输入示例                    输出示例

5                                    3

1 23

12 28

25 35

27 80

36 50

#include<bits/stdc++.h>
using namespace std;
int n,Begins[1000],Ends[1000];
int main()
{
    cin>>n;
    for(int i=0;i<n;i++)
    {
        cin>>Begins[i]>>Ends[i];
    }
    sort(Begins,Begins+n);
    sort(Ends,Ends+n);
    int j=0,ans=0;
    for(int i=0;i<n;i++)
    {
        if(Begins[i]<Ends[j]) ans++;
        else j++;
    }
    cout<<ans;
    return 0;
}

硬币找钱问题

问题描述:

  设有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 枚硬币。这个方案用的硬币个数最少。

编程任务:

  对于给定的各种面值的硬币个数和付款金额,编程计算使用硬币个数最少的交易方案。

数据输入:

每一行有6 个整数和1 个有2 位小数的实数。分别表示

可以使用的各种面值的硬币个数和付款金额。以6 个0 结束。

结果输出:

  输出最少硬币个数。结果应分行输出,每行一个数据。如果不可能完成交易,则输出”impossible”。

输入示例

2 4 2 2 1 0   0.95

2 4 2 0 1 0   0.55

0 0 0 0 0 0

输出示例

2

3

#include<bits/stdc++.h>
using namespace std;
int coins[6];
int coinNum=0;
int pay,realMoney;
int coinsValue[6]={5,10,20,50,100,200};
int changeValue[7]={0,5,10,20,50,100,200};
int contains(int a)
{
   for(int i=0;i<6;i++)
   {
      if(coinsValue[i]==a&&coins[i]>0)
      {
         return i;
      }
   }
   return -1;
}
void greed()
{
  int TempCoinNum=0;
  for(int i=5;i>=0;i--)
  {
     if(coins[i]>0)
     {
        for(int j=0;j<=i;j++)
        {
           realMoney=coinsValue[i]-changeValue[j];
           if(pay>=realMoney)
           {
              if(coins[i]>=pay/realMoney)
              {
                 int TempCoinNum=pay/realMoney;
                 coinNum+=TempCoinNum*2;
                 if(contains(realMoney)!=-1)
                 {
                    TempCoinNum=min(TempCoinNum,coins[contains(realMoney)]);
                    coinNum-=TempCoinNum;
                    coins[contains(realMoney)]-=TempCoinNum;
                 }
                 else coins[i]-=pay/realMoney;
                 pay=pay%realMoney;
                 if(contains(coinsValue[i])==-1) break;
              }
              else
              {
                 coinNum+=coins[i];
                 pay=pay-coinsValue[i]*coins[i];
                 coins[i]=0;
              }
           }
        }
     }
  }
}
int main()
{
   while(!cin.eof())
   {
      coinNum=0;
      for(int i=0;i<6;i++)
      {
         cin>>coins[i];
      }
      if(coins[0]==0&&coins[1]==0&&coins[2]==0&&coins[3]==0&&coins[4]==0&&coins[5]==0) break;
      double cost;
      cin>>cost;
      pay=int(cost*100);
      greed();
      if(coinNum==0||pay!=0) cout<<"impossible"<<endl;
      else cout<<coinNum<<endl;
   }
   return 0;
}

汽车加油问题

问题描述:

  一辆汽车加满油后可行驶n 公里。旅途中有若干个加油站。设计一个有效算法,指出应在哪些加油站停靠加油,使沿途加油次数最少。并证明算法能产生一个最优解。

编程任务:

  对于给定的n 和k 个加油站位置,编程计算最少加油次数。

数据输入:

  第一行有2 个正整数n 和k,表示汽车加满油后可行驶n 公里,且旅途中有k 个加油站。接下来的1 行中,有k+1 个整数,表示第k 个加油站与第k-1 个加油站之间的距离。第0 个加油站表示出发地,汽车已加满油。第k+1 个加油站表示目的地。

结果输出:

  输出最少加油次数。如果无法到达目的地,则输出”No Solution”。

输入示例                    输出示例

7 7                                  4

1 2 3 4 5 1 6 6

#include<bits/stdc++.h>
using namespace std;
int n,k,s[1000];
int num;
int main()
{
    cin>>n>>k;
    for(int i=0;i<=k;i++)
    {
        cin>>s[i];
    }
    int x=s[0];
    for(int i=1;i<=k;i++)
    {
        if(x>n)
        {
            cout<<"No Solution!";
            break;
        }
        else
        {
            x=x+s[i];
            if(x>n)
            {
                num++;
                x=s[i];
                cout<<"在第"<<i<<"个加油站加油"<<endl;
            }
        }
    }
    cout<<num;
    return 0;
}

最优分解问题

问题描述:

  设n 是一个正整数。现在要求将n 分解为若干个互不相同的自然数的和,且使这些自然数的乘积最大。

编程任务:

  对于给定的正整数n,编程计算最优分解方案。

数据输入:

  第1 行是正整数n。

结果输出:

  输出最大乘积。

输入示例         输出示例

10                      30

#include<bits/stdc++.h>
using namespace std;
int n;
int a[1000];
int res=1;
int main()
{
    cin>>n;
    int i=2;
    int sum=0,index=0;
    while(n-sum>=i)
    {
        sum+=i;
        a[i]=i;
        i++;
        index++;
    }
    int p=(n-sum)/index;
    int q=(n-sum)%index;
    for(int j=i-1;j>=2;j--)
    {
        a[j]+=p;
    }
    for(int k=i-1;k>i-1-q;k--)
    {
        a[k]++;
    }
    for(int j=2;j<index+2;j++)
    {
        res=res*a[j];
    }
    cout<<res;
    return 0;
}

程序存储问题

问题描述:

  设有n 个程序{1,2,…, n }要存放在长度为L 的磁带上。程序i 存放在磁带上的长度是li,1≤i≤n 。程序存储问题要求确定这n 个程序在磁带上的一个存储方案,使得能够在磁带上存储尽可能多的程序。

编程任务:

  对于给定的n 个程序存放在磁带上的长度,编程计算磁带上最多可以存储的程序数。

数据输入:

  第一行是2 个正整数,分别表示文件个数n 和磁带的长度L。接下来的1 行中,有n 个正整数,表示程序存放在磁带上的长度。

结果输出:

  输出最多可以存储的程序数。

输入示例                      输出示例

6 50                                  5

2 3 13 8 80 20

#include<bits/stdc++.h>
using namespace std;
int n,l,len[1000],num;
int main()
{
    cin>>n>>l;
    for(int i=0;i<n;i++)
    {
        cin>>len[i];
    }
    sort(len,len+n);
    for(int i=0;i<n;i++)
    {
        if(l>len[i])
        {
            l=l-len[i];
            num++;
        }
        else break;
    }
    cout<<num;
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值