poj 1946 dp(公牛跑圈)

来源:互联网 发布:淘宝卖家发布宝贝教程 编辑:程序博客网 时间:2024/03/29 20:05

题意:一个团队有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 105int 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);}


0 0
原创粉丝点击