poj 1946 dp(公牛跑圈)

题意:一个团队有n只奶牛进行骑自行车环跑,如果一分钟跑x圈,领跑的消耗x * x体力,而后面跟跑的消耗x体力。没有体力的牛可以退场,有一头牛通过重点即算完成比赛。给定N, E, D三个数,表示有N头奶牛,每头奶牛具有初始能量值E,D表示需要环跑的圈数。问奶牛能否完成环跑,如果不能,输出0,否则,输出环跑的最短时间。

思路:dp。显然每头牛轮流领跑,没体力了就退。dp[i][j][k] 表示第i头牛正在领跑(前i-1头已经退场),第i头牛已经消耗了j体力,队伍已经跑完了k圈所用的最小时间。

那么dp[i][j][k] 可以用来更新dp[i][j+a*a][k+a]即当前分钟跑a圈,没更新一次立即更新dp[i+1][k+a]k+a],表示当前分钟跑完第i头牛就退场。最后看看第三维=D(即跑完全程)的最小dp值。

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <queue>
using namespace std;
#define INF 0x3fffffff
#define clr(s,t) memset(s,t,sizeof(s))
#define N 105
int dp[22][N][N];
int n,e,m;
int main(){
    int i,j,k,a,res=INF;
    scanf("%d %d %d",&n,&e,&m);
    clr(dp, 0);
    for(i = 1;i<=n;i++)
        for(j = 0;j<=e;j++)
            for(k = 0;k<=m;k++)
                dp[i][j][k] = INF;
    dp[1][0][0] = 0;
    for(i = 1;i<=n;i++)
        for(j = 0;j<=e;j++)
            for(k = 0;k<=m;k++)
                for(a = 1;j+a*a<=e&&k+a<=m;a++){
                    dp[i][j+a*a][k+a] = min(dp[i][j+a*a][k+a],dp[i][j][k]+1);
                    dp[i+1][k+a][k+a] = min(dp[i+1][k+a][k+a],dp[i][j+a*a][k+a]);
                }
    for(i = 1;i<=n;i++)
        for(j = 1;j<=e;j++)
            if(dp[i][j][m])
                res = min(res,dp[i][j][m]);
    printf("%d\n",res);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值