poj 1946 Cow Cycling DP

来源:互联网 发布:网络开发包括哪些 编辑:程序博客网 时间:2024/04/29 11:58

dp【n】【e】【d】 表示还有n头奶牛,能量为e,跑d圈所需的最短时间

这里只说一下 n > 1的情况

dp【n】【e】【d】 = min( dp【n-1】【e-p】【d-p】 +dp【1】【e】【p】 )

为什么是这样呢?

因为n头奶牛跑d圈,相当于1头奶牛跑了p圈,剩余n-1头跑了d-p圈(注意一点,不管领头的怎么跑,只要跑了p圈,后面的一定是消耗p点能量,所以时间每次与最前面的一头有关)

要注意,这里是根据d来枚举决策,而不是根据e。。。。

我一开始想根据e来决策,想了好久感觉dp维度太多了。。。。。

AC代码如下:

#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>using namespace std;#define MAX 0x3f3f3f3fint dp[22][110][110];int N, E, D;int DFS( int n, int e, int d ){    if( dp[n][e][d] != -1 ){        return dp[n][e][d];    }    if( d == 0 ){        return 0;    }    if( e < d || e == 0 ){        return MAX;    }    dp[n][e][d] = MAX;    if( n == 1 ){        for( int i = 1; i * i <= e && i <= d ; i++ ){            dp[n][e][d] = min( dp[n][e][d], DFS( n, e - i * i, d - i ) + 1 );        }    }else{        for( int i = 1; i <= d; i++ ){            dp[n][e][d] = min( dp[n][e][d], DFS( n - 1, e - i, d - i ) + DFS( 1, e, i ) );        }    }    return dp[n][e][d];}int main(){    while( scanf( "%d%d%d", &N, &E, &D ) != EOF ){        memset( dp, -1, sizeof( dp ) );        int ans = DFS( N, E, D );        if( ans >= MAX ){            cout << 0 << endl;        }else{            cout << ans << endl;        }    }    return 0;}


0 0