Problem B. gBalloon Google APAC 2016 University Test Round D

来源:互联网 发布:python flask下载 编辑:程序博客网 时间:2024/06/07 05:15

这一题类似一个背包问题,在cost限制下实现value的最优。对于每个balloon (Pi,Hi),将它移动到height Hk这个choice即为背包问题中的选择某一个物品,对应的cost是|Hi-Hk|,value是ceil(Pi/Vk)。

因为一个balloon只能选择一个choice,这就类似于分组背包。本来以为直接用分组背包就可以了,但是分组背包是每一组至多选一个物品,而这里面每一组必须选一个物品。Then状态转移方程会不同。

dp[i][j]表示collect了前i个balloon,cost不超过j的最优解。那么遍历第i个balloon所有choice k,dp[i][j]=min(dp[i][j],max(dp[i-1][j-cost],value))。dp[i][j]=0 to k-1中选择某个choice的最优解,max(dp[i-1][j-cost],value)是选择当前choice k的least amount of time。这样就可以判断是否更改为choice k or 维持0 to k-1中某个之前的选择。

这一题最开始WA了,看别人的解法都是二分,还以为算法错了。于是开始看动态规划的最优性原理。o(╯□╰)o。if a1,a2,a3是dp[2][Q]的最优解,那么a1,a2一定是dp[1][Q-cost3]的最优解。Otherwise,假如b1,b2是dp[1][Q-cost3]的最优解,那么背包还可以放进去a3,dp[2][Q]的最优解就是b1,b2,a3了。

这一题大数据跑了半分钟,囧。

#include<iostream>#include<stdio.h>#include<cstdio>#include<string>#include<cmath>#include<stdlib.h>#include<algorithm>#include<string.h>#include<cstring>#include<vector>#include<queue>#include<map>#include<set>using namespace std;//2016 Round D Problem B. gBalloonint T;const int maxn=110;int N;int M;int Q;int P[maxn];int H[maxn];int V[maxn*10];int dp[110][10010];const int INF=0x3f3f3f3f;int main(){    freopen("B-large-practice.in","r",stdin);//    freopen("input.txt","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d",&T);    for(int ca=1;ca<=T;ca++)    {        memset(P,0,sizeof(P));        memset(H,0,sizeof(H));        memset(V,0,sizeof(V));        memset(dp,0x3f,sizeof(dp));        scanf("%d %d %d",&N,&M,&Q);        for(int i=0;i<M;i++)        {            scanf("%d",&V[i]);        }        for(int i=0;i<N;i++)        {            scanf("%d %d",&P[i],&H[i]);        }        for(int i=0;i<N;i++)        {            for(int j=0;j<=Q;j++)            {//                dp[i][j]=INF;                for(int k=0;k<M;k++)                {                    if(V[k]==0)                    {                        continue;                    }                    else if(V[k]*P[i]>0)                    {                        continue;//can not reach (0, y)                    }                    else                    {                        int cost=abs(H[i]-k);                        int value=(abs(P[i])+abs(V[k])-1)/abs(V[k]);//ceil(1.0*abs(P[i])/abs(V[k]));                        if(j>=cost)                        {                            if(i==0)                            {                                dp[i][j]=min(dp[i][j],value);                            }                            else                            {//                                dp[i][j]=min(dp[i-1][j],max(dp[i-1][j-cost],value));                                dp[i][j]=min(dp[i][j],max(dp[i-1][j-cost],value));                            }//                            cout<<P[i]<<" "<<V[k]<<" "<<endl;//                            cout<<i<<" "<<j<<" "<<k<<" "<<cost<<" "<<value<<" "<<dp[i][j]<<endl;                        }                    }                }            }        }        if(dp[N-1][Q]==INF)        {            printf("Case #%d: IMPOSSIBLE\n",ca);        }        else        {            printf("Case #%d: %d\n",ca,dp[N-1][Q]);        }    }    return 0;}


0 0
原创粉丝点击