1 条题解
-
0
定义dp[i][j][k]表示第i头牛领头,此时消耗j点能量,走了k圈的最少时间
如果此时更换领头的牛,dp[i][k][k]=min{dp[i-1][j][k],dp[i][k][k]}
否则,dp[i][j][k]=min{dp[i][j][k],dp[i][j-sqr(x)][k-x]+1}
状态定义完后凭空想转移不好想,对着题目给的策略自己手推了下第一头牛和第二头牛的式子,马上就能写出方程了:)
最后枚举下答案dp[i][j][d]就行 —
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> #include <queue> #include <vector> #include <utility> #include <set> //#define LOCAL #define maxe 105 #define maxd 105 #define maxn 25 using namespace std; typedef long long ll; typedef pair<int,int> P; int n,E,D; int dp[maxe][maxd],f[maxn][maxd]; int main(){ #ifdef LOCAL freopen("sample.in","r",stdin); freopen("sample.out","w",stdout); #endif scanf("%d%d%d",&n,&E,&D); if(E < D){ puts("0"); return 0; } memset(dp,0x3f,sizeof(dp)); for(int i=0;i<=E;i++) dp[i][0] = 0; for(int i=1;i<=E;i++){ for(int j=1;j<=D;j++){ for(int k=1;k <= j && k * k <= i;k++){ dp[i][j] = min(dp[i][j],dp[i - k * k][j - k] + 1); } } } memset(f,0x3f,sizeof(f)); f[0][0] = 0; for(int i=1;i<=n;i++){ for(int j=0;j<=D;j++){ int p = D - j; for(int k=0;k<=j;k++){ f[i][j] = min(f[i][j],f[i - 1][j - k] + dp[E - p][k]); } } } printf("%d\n",f[n][D]); return 0; }
- 1
信息
- ID
- 947
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- 递交数
- 2
- 已通过
- 1
- 上传者