poj~3273(二分法)

本文深入探讨了如何利用二分法解决POJ3273问题,即如何将一组数值分成指定数量的组,使得各组的花费之和尽可能小,并特别关注花费最大的一组。通过不断调整二分值来寻找最优解,实现复杂问题的高效求解。

poj3273

第一个做的二分法,以前一直以为二分法只能用在查找上,没想到二分那么神奇,还可以这样用。

该题的意思是:给你n个数,让你分成m分,要求分得各组的花费之和应该尽可能地小,然后输出花费最大的那组。


解题思路是,不断的二分这n组分成任意分的最大值,具体的还是看代码吧,详细在注释里。

#include <stdio.h>
#define MAX 100005

int n,m;


int check(int mid,int money[])
{
    int group=1,i;      //份数从1开始
    int sum=0;
    for(i=1;i<=n;i++)
    {
        if(sum+money[i]<=mid)
            sum+=money[i];
        else
        {
            group++;
            sum=money[i];
        }
    }
    if(group>m)         //分的组数太多,即mid太小 
        return 1;
    else
        return 0;
}
int main()
{
    while(scanf("%d %d",&n,&m)!=EOF)
    {
        int  money[MAX];
        int i,low=0,high=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&money[i]);
            low=low>money[i]?low:money[i];      //当最多分成n份时,下界为所有数的最大值
            high+=money[i];                     //上界为所有数之和
        }
        int mid=(low+high)/2;
        while(low<high)             //不断二分找分成份数最靠近m的mid的最小值
        {
            if(check(mid,money))    //mid太小 ,即分的组数太多
               low=mid+1;
            else
                high=mid-1;
            mid=(low+high)/2;
        }
        printf("%d\n",mid);         //最后得出最合适的值mid
    }
    return 0;
}


POJ 2503 是一个在线翻译的题目,要实现一个简单的英 - 外语词典,输入外语单词后输出对应的英语单词。使用二分法解决该问题的步骤如下: 1. 读取输入的词典数据,将英语单词和对应的外语单词存储起来。 2. 对存储的外语单词按字典序排序。 3. 对于每个查询的外语单词,使用二分法在排序后的列表中查找其对应的英语单词。 以下是实现代码: ```cpp #include <iostream> #include <algorithm> #include <string> #include <vector> using namespace std; struct WordPair { string english; string foreign; }; // 比较函数,用于按外语单词排序 bool compare(const WordPair& a, const WordPair& b) { return a.foreign < b.foreign; } // 二分查找函数 string binarySearch(const vector<WordPair>& words, const string& target) { int left = 0, right = words.size() - 1; while (left <= right) { int mid = left + (right - left) / 2; if (words[mid].foreign == target) { return words[mid].english; } else if (words[mid].foreign < target) { left = mid + 1; } else { right = mid - 1; } } return "eh"; } int main() { vector<WordPair> words; string line; // 读取词典数据 while (getline(cin, line) && line != "") { int spacePos = line.find(' '); WordPair wp; wp.english = line.substr(0, spacePos); wp.foreign = line.substr(spacePos + 1); words.push_back(wp); } // 按外语单词排序 sort(words.begin(), words.end(), compare); // 处理查询 while (getline(cin, line)) { cout << binarySearch(words, line) << endl; } return 0; } ``` 上述代码首先定义了一个 `WordPair` 结构体来存储英语单词和对应的外语单词。接着,读取输入的词典数据并存储在 `words` 向量中。之后,使用 `sort` 函数按外语单词对 `words` 进行排序。对于每个查询的外语单词,调用 `binarySearch` 函数进行二分查找,若找到则返回对应的英语单词,未找到则返回 `"eh"`。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值