您的位置:首页 > 大数据 > 人工智能

Regionals 2015 >> Asia - Tehran >> 7527 - Funfair【贪心】【dp】

2016-08-02 17:34 363 查看

7527 - Funfair



题目链接:7527

题目大意:玩一个闯关游戏,初始为x元,总共有n关,自己选择k关,以及过关顺序。过第i关的时候,赢得概率为pi,赢了之后可获得ai元,输了的话,则输去li * x的钱.问如何选择关以及闯关顺序使得最后的金钱数期望最大。

题目思路:首先,需要将关排序,这样可以保证第i+1关一定在i关之后过,然后进行dp,第i关取或者不取。

排序方式: 我们可以知道,过第i关的时候

赢: (Ai + x) * Pi
输: (1 - Pi)(1 - Li) * x

相加合并一下得到(1 - Li + LiPi) * x + Ai * Pi
假设 c = (1 - Li + LiPi)
d = Ai * Pi
即: cx + d
那么,在考虑先过A关还是B关的时候,有两种可能性,
先过A关:c2 * (c1*x+d1) + d2;
先过B关:c1 * (c2*x+d2) + d1;
假设A大于B,c2 * (c1*x+d1) + d2 > c1 * (c2*x+d2) + d1
化简得到,d1/(c1-1) < d2/(c2-1)


所以:按照 d1/(c1-1) < d2/(c2-1) 方式排序即可。

注意:

1.排序的时候需要考虑c等于1的情况(分母不能为0)

2.p,l代进去算的时候要除以100(因为他们是百分比)

最后dp处理一下就可以了!

以下是代码:

#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <functional>
#include <numeric>
#include <string>
#include <set>
#include <map>
#include <stack>
#include <vector>
#include <queue>
#include <deque>
#include <list>

using namespace std;
#define eps 1e-6
struct node
{
double a,l,p,c,d,s;
}g[105];
bool cmp(node a, node b)
{
if (a.c == 1 || b.c == 1) return a.c < b.c;  //比较坑!
return a.s > b.s;
}
double dp[105][105];
int main()
{
int n,k,x;
while(cin >> n >> k >> x)
{
if (n == 0 && k == 0 && x == 0) break;
memset(dp,0,sizeof(dp));
memset(g,0,sizeof(g));
for (int i = 0; i < n; i++)
{
cin >> g[i].a >> g[i].l >> g[i].p;
g[i].l /= 100;
g[i].p /= 100;
g[i].c = 1 - g[i].l + g[i].l * g[i].p;
g[i].d = g[i].a * g[i].p;
g[i].s = g[i].d / (g[i].c - 1);
}
sort(g,g + n,cmp);
for (int i = 0; i < n; i++) dp[i][0] = x;

for (int i = 0; i < n; i++)  //第i个活动选不选
{
dp[i][1] = max(x * g[i].c + g[i].d,dp[i][1]);
for (int l = 0; l < i; l++) //在前l个活动中
{
for (int j = 2; j <= min(l+2,k); j++)  //选了j个
{
dp[i][j] = max(dp[i][j],dp[l][j - 1] * g[i].c + g[i].d);

}
}
}
double ans = 0;
for (int i = 0; i < n; i++) ans = max(dp[i][k],ans);
printf("%.2f\n",ans);
}
}


附上几组测试数据:

/*输入*/
5 3 100
46 15 13
42 36 7
61 71 37
79 89 57
18 99 18

10 5 1000
30 63 64
71 41 41
45 14 27
69 98 91
64 58 23
45 98 93
60 14 87
73 87 82
27 88 75
46 12 32

20 1 10
22 94 19
10 23 91
53 53 73
26 47 96
48 64 54
73 70 96
61 59 58
28 49 63
36 4 35
27 91 52
35 87 32
88 67 58
62 59 60
17 55 58
72 4 52
37 89 26
70 17 33
89 33 10
71 93 61
28 7 88

20 5 10
29 85 12
54 8 14
84 71 16
82 15 3
59 22 71
76 4 33
67 2 97
82 96 52
87 22 25
30 47 30
75 13 25
47 14 80
39 11 75
28 26 94
28 27 34
89 80 3
58 60 32
23 88 32
45 86 56
14 0 63

/*输出*/

90.67
860.39
79.80
213.04
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  区域赛 贪心 dp