1 条题解

  • 0
    @ 2025-4-11 16:44:53

    定义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
    上传者