URAL 1755 Cake
来源:互联网 发布:医疗数据采集 编辑:程序博客网 时间:2024/06/05 17:36
链接:http://vjudge.net/problem/viewProblem.action?id=24604
题解:这道题说清楚挺麻烦的,我就盗用一下中山大学 LiYuzhu 同学的题解吧,版权所属,不要来找我。代码一份是他的,一份是我的。
题目大意:
Karlsson和 LittleBoy想要分割一块含有 n克奶油和 m克巧克力的蛋糕,由 LittleBoy切割,Karlsson先选。每个人对蛋糕的估值函数不同,Little Boy的为 a1x + b1y,Karl的为 a2x + b2y。现给出四个系数和 n,m,求一种能使 LittleBoy收益最大的切割方式。其中,Little Boy可以在不超过 n和 m的范围下,切割出含有任意克奶油和巧克力的蛋糕。而当两块蛋糕对 Karlsson来说估值相同时,Karlsson会让出对 Little Boy 来说估值较高的那一块。
思路:
首先,想要使 Little Boy的收益最高,约束就是使得两块蛋糕对 Karl来说估值一样。
设两块蛋糕中任意一块有 x克奶油和 y克巧克力,则应有
a2x + b2y = a2(n - x) + b2(m - y)
可以用反证法证明,假设 a2x + b2y < a2(n - x) + b2(m - y),那么 Karl会选择 n–x克奶油和 m–y克巧克力的蛋糕,而 LittleBoy会得到 x克奶油和 y克巧克力的蛋糕。
但是必定存在 x+Δx和 y+Δy,使得
a2(x + Δx) + b2(y + Δy) = a2(n – x -Δx) + b2(m – y - Δy)成立,
而这时对 LittleBoy来说,显然 x+Δx克奶油和 y+Δy克巧克力的蛋糕相比原来的蛋糕收益更高。
a2x + b2y > a2 (n - x) + b 2(m - y) 的情况同理可证。
答案只要求输出符合题意的任意一种分割方法中的任意一块的含奶油和巧克力量,不妨设 LittleBoy得到的是(x,y)的那一块。
题目要求让 LittleBoy的估值函数 V = a1 x + b1 y 最大。从 a2x + b2y = a2(n - x) + b2(m - y)可以得到 y和 x的关系式,代入函数 V中,可得到 V和 x的关系式,为一次函数 V(x) = kx + b。
接下来只要根据 k的正负,来确定使得 V(x)最大的 x的值,在通过上面的约束条件算出 y即可,注意需确保 x和 y在取值范围内。
如果 k < 0,则确保 x越小越好,因此直接取 x = 0,算出 y,判断 y是否在 0 ~ m 范围内,如果不在,则令 y = m,反算出 x 即可。
如果 k > 0,则确保 x越大越好,因此直接取 x = n,算出 y,判断 y是否在 0 ~ m 范围内,如果不在,则令 y = 0,反算出 x 即可。
如果 k = 0 的,代表可以随意确定 x,那么随便套用上面一种情况即可。
有几种特殊情况:
通过计算可知 k = a 1 – a2 * b1 / b 2,而且在确保 x和 y在取值范围内时 a 2 也会出现在分母,因此对于 a 2 和 b 2 等于 0的情况特殊对待。
a2 =b2 =0,则 x = n,y = m,即 LittleBoy拿走全部
a2 = 0, b2 ! = 0 ,则 x = n,y = m / 2,即 LittleBoy拿走全部奶油,而巧克力对半分即可
a2 ! =0 ,b 2 =0 , 则 x = n / 2,y = m,即 LittleBoy拿走全部巧克力,而奶油对半分即可
LiYuzhu 同学的代码:
#include<iostream>#include<iomanip>using std::cin;using std::cout;using std::endl;int main(void){ double a1,b1,a2,b2; double n,m; double x,y; cin>>a1>>b1>>a2>>b2; cin>>n>>m; //步骤 1 if(a2==0 && b2==0) { x=n; y=m; } else if(a2==0&&b2!=0) { x=n; y=m/2; } else if(a2!=0&&b2==0) { x=n/2; y=m; } //步骤 2,y和 x的关系式均由约束方程化简得到 else if((a1-a2 *b1/b2)<0.0) { x=0; y=(n*a2/b2+m)/2; if(y>m) { y=m; x=(n-m*b2/a2)/2; } } else if((a1-a2 *b1/b2)>0.0) { x=n; y=((n-2*x)*a2/b2+m)/2; if(y<0) { y=0; x=(n+m*b2/a2)/2; } } else { x=0; y=(n*a2/b2+m)/2; if(y>m) { y=m; x=(n-m*b2/a2)/2; } } //步骤 3 cout<<std::setiosflags(std::ios::fixed)<< std::setprecision(8)<<x<<" "<<y<<endl; return 0;}
我的:
#include <iostream>#include <cstring>#include <string>#include <iomanip>using namespace std;int main(){double a1,b1,a2,b2;double x,y;cin>>a1>>b1>>a2>>b2;cin>>x>>y;double h = (a2*x + b2*y)/2.0;double y1 = h/(b2*1.0);double x2 = (h - b2*y)/(a2*1.0);double x3 = h/(a2*1.0);double y4 = (h - a2*x)/(b2*1.0);double ness = 0;double ansx,ansy;if(y1 >= 0 && y1 <= y){if(b1*y1 > ness){ansx = 0,ansy = y1;}}else if(x2 >= 0 && x2 <= x){if(a1*x2 + b1*y > ness){ansx = x2,ansy = y;}}else if(x3 >= 0 && x3 <= x){if(a1*x3 > ness){ansx = x3,ansy = 0;}}else if(y4 >= 0 && y4 <= y){if(a1*x + b1*y4 > ness){ansx = x,ansy = y4;}}cout<<fixed<<setprecision(8)<<ansx<<' '<<fixed<<setprecision(8)<<ansy<<endl;return 0;}
- URAL 1755 Cake
- cake
- Cake
- Cake
- Cake
- Cake
- Cake
- Cake
- Cake
- cake
- Cake
- Cake
- Cake
- Cake
- Cake
- Cake
- Cake
- Cake
- 搭建OJ-这个版本 并一直解决 RE 问题
- 软件开发流程
- 百度之星资格赛 1004 Labyrinth
- 外星人供给站
- malloc/free与new/delete的区别
- URAL 1755 Cake
- codeforces 432c Prime Swaps
- 两个有序单链表合并
- 外网访问内网应用实现之无公网IP、多端口、固定端口、UDP等应用的实现方法
- poj1655 Balancing Act 【树形DP(很弱)】
- C++拷贝构造函数的几个细节
- ABB RAPID 在 Notepad++ 中语法高亮的实现
- LeetCode: Swap Nodes in Pairs [023]
- MBR结构解析与fdisk的bash实现