USACO FEB 2002 CowCycling(奶牛玩具车队赛)

本题大意如下:

CowCycling

Description

有N头奶牛组队参加一个玩具车队比赛.比赛在体育场内进行,共需绕场S圈.车队在比赛时排成一列,由于空气阻力的作用,领队奶牛消耗的电力要比后面的多.每头奶牛控制的车的初始电力都是相同的,记作M,电力减为负数的玩具车会立即停止,无法继续比赛,电力在比赛中无法恢复,但只要有一辆车到终点就算完成比赛.
比赛的最小单位时间是分钟.车队在每分钟必须绕赛场整数圈,最少一圈.每过一分钟,车队可以自由地更换领队,只要领队车有足够的电力,车队也可以自由地改变车速.在一分钟里,如果车队绕场X圈,领队奶牛将会消耗X^2点电力,后面的奶牛会消耗X点电力,设定速度时,要保证领队奶牛在一分钟内不会掉队.
作为玩具车大师,请你计划一下,在比赛进行的每分钟内,应采用什么策略才能让车队以最快的时间完成比赛?
PS:数据保证可以完成比赛.

Input Description

第一行:三个整数:N,M,S,1<=N<=20,1<=S<=M<=100

Output Description

单个整数:表示最早完成比赛的时间

Sample Input

3 30 20

Sample Output

7

Data Size & Hint

首先这题dp的状态有点难定义
但是必究直观的思路就是根据题目的N,M,S定义三维dp
第一维i自然是已经使用的跑完的圈数
第二维j是还剩下的羊的只数
第三维k是领头羊剩余的电力
存储当前状态下的最小时间
很容易知道,当一只领头羊的电力没了以后,就可以丢掉不管了
有下一只羊领头,这只羊的电力自然是m-已经跑完的圈数
所以可以列出状态转移方程如下:
dp[i][j-1][m-i]=min(dp[i][j-1][m-i],dp[i][j][k])
还有第四层for。。。。
代表当前领头羊领队的圈数
转移方程
dp[dis+i][j][q-dis*dis]=min(dp[dis+i][j][q-dis*dis],dp[i][j][q]+1);
于是这题就没了
话说我不知道这究竟是什么类型的dp

代码如下:

//又慢内存又大的lowest代码
#include
#define oo 2000000000
#define M 105
#define N 25
int dp[M][N][M];
int main(){
    int n,m,k,ans=oo;
    scanf("%d %d %d",&n,&m,&k);
    for(int i=0;i<=k;i++)
        for(int j=0;j<=n;j++)
            for(int q=0;q<=m;q++)dp[i][j][q]=oo;
    dp[0][n][m]=0;//大哥,初值没有会死的
    for(int i=0;i=1;j--)
            for(int q=m;q>=0;q--){
                if(j>1&&dp[i][j-1][m-i]>dp[i][j][q])
                    dp[i][j-1][m-i]=dp[i][j][q];
                for(int dis=1;dis<=k-i&&dis*dis<=q;dis++)
                    if(dp[dis+i][j][q-dis*dis]>dp[i][j][q]+1)
                        dp[dis+i][j][q-dis*dis]=dp[i][j][q]+1;
            }
    for(int j=1;j<=n;j++)
        for(int q=0;q<=m;q++)
            if(ans>dp[k][j][q])ans=dp[k][j][q];
    printf("%d\n",ans);
    return 0;
}

你可能感兴趣的:(dp,USACO)