ZCMU-1111

image
image

与背包和动态规划有关(我认为)


  1. 采用dp数组存放吃掉i千克食物要用掉的钱
  2. dp最开始要尽量的大方便过程中判断和最后的输出判断
  3. 实时更新dp,保留最小的钱

以前不知道的

  • printf函数可以这样用
  • fill函数填充数组,(开始,结束,填充值);
  • C和C++结构体里面可以放函数
    学习

#include<cstdio>
#include<algorithm>
//包含 fill 函数 
using namespace std;
const int infinite=999999;
struct food{
    int a,b,c;
    //可以在结构体中加函数
	//无论C++或者C 
    void inputA(){
        scanf("%d",&a);
    }
    void inputB(){
        scanf("%d",&b);
    }
    void inputC(){
        scanf("%d",&c);
    }
};

int main(){
    int n,m;
    food f[1005];
    int i,j,k,dp[10005];
    //dp表示吃掉ikg花费的最小金额 
    while(~scanf("%d%d",&n,&m)){
    	
        for(i=0;i<n;i++)f[i].inputA();
        for(i=0;i<n;i++)f[i].inputB();
        for(i=0;i<n;i++)f[i].inputC();
        fill(dp,dp+1+m,infinite);
        
        *dp=0;//dp[0]表示吃掉0千克花费金额
		 
        for(i=0;i<n;i++){
        	//开始处理数据 
            for(j=m;j>=0;j--){
            	
            //只能从后到前,不能反过来
            //dp[j]因为大的是从小的过来
			//如果从0开始,这会重复加许多 
			
                if(dp[j]==infinite)continue;
                for(k=1;k<=f[i].c;k++){
                	//一分一分的加上来 
                    if(j+k*f[i].a>=m){
                        //大于m就直接上在dp[m]上,
						//因为可以超过他要吃的 
                        dp[m]=min(dp[m],dp[j]+k*f[i].b);
                        break;
                        //因为当前已经超过了 
                    }
                    dp[j+k*f[i].a]=min(dp[j+k*f[i].a],dp[j]+k*f[i].b);
                     
                }
            }
        }
        printf(dp[m]==infinite?"Impossible\n":"%d\n",dp[m]);
    }
    return 0;
}
posted @ 2024-04-29 19:24  海&贼  阅读(1)  评论(0编辑  收藏  举报