Regionals 2010, Asia - Kuala Lumpur

来源:互联网 发布:跨境电商erp系统源码 编辑:程序博客网 时间:2024/05/22 12:45

C题:Scientefic Experiment

题意:让你走进一个建筑扔鸡蛋,测试鸡蛋的硬度,即求出在哪层扔开始碎。进入建筑需要花费y元(不带鸡蛋),花费z元(带鸡蛋),在建筑里买鸡蛋需要花费x元。

开始一直没搞清楚题意,第一组和第二组样例出的时候,都是根据二分的思想来做的,不过对于后面的样例就不适用了。在看了xl的代码后,想到要枚举最后一次测试的层数,并且利用动态规划来搞。

f[i]表示要执行i次的最坏情况的最小花费,注意这里考虑的是从外面走进建筑的费用。

通过枚举最后一次测试的层数:

第一层和最后一层:

f[i-1]+z  (通过测试1-(i-1)层,最后一次没碎则要测试第i层)

f[i-1]+x+y(测试2-(i)层,最后一次一次碎了则要测试第1层)

其他层可以有两种方式过来:

左边:f[j-1]+z

右边:f[i-j]+x+y

2<=j<=i-1

这题和上次那题差不多,通过枚举最后一个元素的情况来进行状态转移。

代码:

#include<iostream>#include<cstdio>#include<vector>#include<string>#include<queue>#include<cmath>#include<algorithm>#include<cstring>#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define maxn 1005#define INF 0xfffffff#define mem(a,b) memset(a,b,sizeof(a))#define FOR(i,s,t) for(int i=s;i<=t;i++)#define ull unsigned long long#define ll long longusing namespace std;int n,x,y,z;int f[maxn];int main(){    int t,tt=1;    scanf("%d",&t);    while(t--)    {        scanf("%d%d%d%d",&n,&x,&y,&z);        int tmp;        f[0]=0,f[1]=x+y;        for(int i=2;i<n;i++)        {            f[i]=min(f[i-1]+z,f[i-1]+x+y);//第i-1次碎了测试第一层,没碎测试最后一层的最坏情况            for(int j=2;j<=i-1;j++)//最后一次测试其他层            {                tmp=max(f[j-1]+z,f[i-j]+x+y);                f[i]=min(tmp,f[i]);            }        }        printf("Case %d: %d\n",tt++,f[n-1]);    }return 0;}


原创粉丝点击