分治总结1

本文通过五个典型问题:化装晚会、循环赛安排、小车问题、木材加工和奇怪的函数,深入讲解了分治算法在解决实际问题中的应用。包括如何通过优化策略将复杂度降低到线性,并给出了具体的解决方案和思路。
摘要由CSDN通过智能技术生成
问题 K: 【分治】化装晚会

题目
万圣节又到了!FJ打算带他的奶牛去参加化装晚会,但是,FJ只做了一套能容下两头总长不超过S (1≤S≤1000000)的奶牛恐怖服装。FJ养了N(2≤N≤20000)头按1–N顺序编号的奶牛,编号为i的奶牛的长度为L_i(1≤L_i≤1000000)。如果两头奶牛的总长度不超过S,那么她们就能穿下这套服装。
FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。
输入
第1行是2个整数:N和S;
第2~N+l行每行一个整数:L_i。
输出
1个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的。
思路
首先想到可以排序后对每头牛i二分搜索和它满足条件的第二头牛j,,则比j长度小的牛也都满足条件,枚举第一头牛+二分搜索,复杂度O(nlogn)。
如果从大向小枚举i,那么其实没必要每次重新二分找j,因为满足前一头牛的j一定满足当前的牛。所以j可以按从小到大的顺序移动。复杂度降为O(n)。
细节见代码:

#include <iostream>
#include <algorithm>
#define rep(i,j,n) for(register int i=j;i>=n;i--)
using namespace std;
int a[20005];
int main()
{
   
    int n,s;
    cin>>n>>s;
    for(int i=1;i<=n;i++) cin>>a[i];
    sort(a+1,a+n+1);
    int cnt=0;
    int j=1;
    rep(i,n,1)
    {
   
        while(j<=n&&a[i]+a[j]<=s) j++;
        if(i>=j) cnt+=j-1;
        else cnt+=j-2;
    }
    cout << cnt/2 << endl;
    return 0;
}


问题 C: 【分治】循环赛问题

题目:
设有n个选手的网球循环比赛,其中n=2k(0≤k<7)。现要设计一个满足以下条件的比赛日程表:
(1)每名选手要与其他n-1名选手都进行一次比赛;
(2)每名选手每天只赛一次;
(3)整个比赛共进行n-1天,要求每天没有选手轮空。
输入
选手人数n(n≤100),n只能为2的整数次幂。
输出
N阶方阵A[l…n,0…n-l],当j>0时,A[i,j]表示第i名运动员在第j天所遇到的比赛对手(A[i,0]=i),每个数据占5位宽度。
思路
如下图所示是k=3时的一个可行解(第1列是选手编号),它是4块拼起来的。 左上角是k=2时的一组解,左下角是左上角每个数加4得到,而右上角、 右下角分别由左下角、 左上角复制得到。
在这里插入图片描述
代码

#include <iostream>
#include <cstdio>
using namespace std;
int ans[105
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值