hud上的动态规划练习

来源:互联网 发布:html5权威指南 源码 编辑:程序博客网 时间:2024/05/17 03:01

1、hud 2955 Robberies
(转载,你会发现dp下标是什么以及内容存储什么是很重要的)

第一点就是最容易犯错的一点,把所求总被抓概率看成背包容量。这就有两个很明显错误,求的就是1-被抓概率=逃跑概率,限制条件和最大背包容量不能同为一属性。再者,概率为多为浮点数,精确度不高无法遍历。所以背包容量必然是钱数,因为他能抢的银行有限,钱数也是有限的。然后是求最大逃跑概率,而题中每项给出的是被抓概率,所以要先被1减一下。还有最后求得的逃跑概率随着抢银行的数量增加而减少,多抢一个银行,其钱数必将转化为概率的乘积,所以动态方程也要做出改变。最后遍历,剩余的钱数越多,说明所抢的钱数越少,逃跑几率越大。所以从大到小遍历背包容量,一旦大于p,即为最大概率跳出。

#include <stdio.h>#include <algorithm>#include <iostream>#include <cmath>#include <string.h>using namespace std;const int N = 50005;int main(){  //  freopen("in.txt", "r", stdin);    int t, m0, m[N];    double p0, p[N], ans[N];    scanf("%d", &t);    while(t --)    {        scanf("%lf%d", &p0, &m0);        int sum = 0;        for(int i = 0; i < m0; i ++)        {            scanf("%d%lf", &m[i], &p[i]);            sum += m[i];        }        memset(ans, 0, sizeof(ans));        ans[0] = 1;        for(int i = 0; i < m0; i ++)        {            for(int j = sum; j >= m[i]; j --)            {                ans[j] = max(ans[j], ans[j - m[i]] *(1 - p[i]));            }        }        for(int i = sum; i >= 0; i --)        {            if(ans[i] > (1 - p0))            {                printf("%d\n", i);                break;            }        }    }    return 0;}

2、hud 1864 最大报销额
最主要的是将数据扩大100倍 dp[j]=max(dp[j],dp[j-v[i]]+v[i])

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#define MAXNUM 3000050using namespace std;int N, dp[MAXNUM], bill[35];float sum;int main(){    //freopen("1.txt", "r", stdin);    int i, j, k, t, res, total, n[3];    char c;    float cash;    bool flag;    while (scanf("%f%d", &sum, &N) != EOF&&N)    {        memset(dp, 0, sizeof(dp));        memset(bill, 0, sizeof(bill));        total = (int)(100 * sum);        t = 0;        for (i = 0; i < N; i++)        {            memset(n, 0, sizeof(n));            flag = 1;            scanf("%d", &k);            for (j = 0; j < k; j++)            {                scanf(" %c:%f", &c, &cash);                if (c == 'A' || c == 'B' || c == 'C')                    n[c - 'A'] += (int)(cash * 100);                else                    flag = 0;            }            res = n[0] + n[1] + n[2];            if (n[0] <= 60000 && n[1] <= 60000 && n[2] <= 60000 && flag&&res<=100000)                bill[t++] = res;        }        for (i = 0; i < t; i++)        {            for (j = total; j >= bill[i]; j--)            {                dp[j] = max(dp[j - bill[i]] + bill[i], dp[j]);            }        }        printf("%.2f\n", float(float(dp[total]) / 100));    }    return 0;}

3、hdu 1231 最大连续子序列

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#define MAXNUM 10010using namespace std;int N, dp[MAXNUM], start[MAXNUM], num[MAXNUM];int main(){    //freopen("1.txt", "r", stdin);    int i, j, k, t, ans, total, end;    bool flag;    while (scanf("%d", &N) && N)    {        memset(dp, 0, sizeof(dp));        memset(start, 0, sizeof(start));        memset(num, 0, sizeof(num));        flag = 1;        for (i = 1; i <= N; i++)        {            scanf("%d", &num[i]);            if (flag&&num[i] >= 0)                flag = 0;        }        if (flag)        {            printf("0 %d %d\n", num[1], num[N]);            continue;        }        ans = dp[1] = num[1];        start[1] = 1;        end = 1;        for (i = 2; i <= N; i++)        {            if (dp[i - 1] >= 0)            {                start[i] = start[i - 1];                dp[i] = num[i] + dp[i - 1];            }            else            {                start[i] = i;                dp[i] = num[i];            }            if (dp[i] > ans)            {                ans = dp[i];                end = i;            }        }        printf("%d %d %d\n", ans, num[start[end]], num[end]);    }    return 0;}

4、hdu 1506 Largest Rectangle in a Histogram

最开始我想的是每一个都去比较一下,结果超时了

for (i = 2; i <= N; i++)        {            dp[i] = tmp = num[i];            t = 1;            for (j = i - 1; j >= 1; j--)            {                tmp = min(tmp, num[j]);                dp[i] = max(dp[i], tmp*(++t));            }            ans = max(dp[i], ans);        }

结果看了网上的别人的代码才发现,dp[i]每次记录的是包含i矩形的最大值即可。
最主要的还是引进了L数组和R数组,类似于find_union的思想;

while (num[i] <= num[j + 1] &&j < N)                j = R[j + 1];

这个代码之前写错了,应该是j

#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<queue>#include<algorithm>#define MAXNUM 100010using namespace std;int N;long long num[MAXNUM], L[MAXNUM], R[MAXNUM];int main(){    freopen("1.txt", "r", stdin);    int i, j, k, t, l, r;    long long ans, tmp;    while (scanf("%d", &N)!=EOF && N)    {        for (i = 1; i <= N; i++)        {            scanf("%lld", &num[i]);        }           L[1] = 1;        R[N] = N;        for (i = 2; i <= N; i++)        {            j = i;            while (num[j - 1] >= num[i] && j > 1)                j = L[j - 1];            L[i] = j;        }        for (i = N-1; i >= 1; i--)        {            j = i;            while (num[i] <= num[j + 1] &&j < N)                j = R[j + 1];            R[i] = j;        }        ans = 0;        for (i = 1; i <= N; i++)        {            tmp = (R[i] - L[i] + 1)*num[i];            if (tmp > ans)                ans = tmp;        }        printf("%lld\n", ans);    }    return 0;}
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新手眉毛修坏了怎么办 小麦补贴卡丢了怎么办 种粮大户没粮仓怎么办? 公司不发高温费怎么办 低保户没低保证怎么办 鸿运当头花干了怎么办 鸿运当头花谢了怎么办 鸿运当头花不红怎么办 众筹项目失败了怎么办 孕妇头发白了怎么办呢 猕猴桃坏了吃了怎么办 猕猴桃买的太硬怎么办 金艳猕猴桃很硬怎么办 猕猴桃又硬又酸怎么办 2岁宝宝生长缓慢怎么办 婴儿体重长得慢怎么办 人吃了乌药中毒怎么办 水中的氧气过少怎么办 怀孕9个月血糖高怎么办 怀孕的人血糖高怎么办 来月经很痛该怎么办 月经来了好痛怎么办 花呗额度用完了怎么办 老人长期卧床长了褥疮怎么办 5岁宝宝嗓子哑了怎么办 2岁宝宝喉咙嘶哑怎么办 1岁宝宝嗓子哑了怎么办 3个月婴儿嗓子哑怎么办 小孩一感冒就喘怎么办 狗打双黄连过敏怎么办 过敏怎么办怎么好的快 铁木砧板变形了怎么办 水泥地面起沙严重怎么办 横厅沙发不靠墙怎么办 吃多了胃疼怎么办 龙血树叶子干枯怎么办 龙血树叶尖发黄怎么办 茶花叶子掉光了怎么办 鸡虱子爬人身上怎么办 鸡的身上有虱子怎么办 鸡跳蚤在人身上怎么办