• The Preliminary Contest for ICPC Asia Shenyang 2019


    C. Dawn-K's water (完全背包)

     

    样例输入

    3 3
    2 1
    3 1
    1 1
    3 5
    2 3
    1 2
    3 3
    

    样例输出

    3 3
    3 6
    

    题意分析:

    不同的水有不同的价格,要求买到至少m千克的水,输出花的最少的钱和实际买到的水的重量。

    解题思路:

    题目和完全背包差不多,主要有两个难点:可以买超过m的水,需要求实际买到的水的重量。

    用dpv[i]表示买重量为i的水需要的最少的钱,

    用dpw[i]表示买重量为i的水实际买到的水的重量,这个地方需要好好理解一下,如果我买i+x的水花的钱要低于买i的水的钱,我可以直接买i+x重量的水。

    下面就是相当于完全背包,当 j-a[i].w < 0 时,也就是第i瓶水的重量大于所需要的重量 j 的时候,比较一下价格的大小,如果a[i].v更小, 那么我可以用更少的钱买到更多的水,所以可以更新dpv[j]和dpw[j]。

    j-a[i].w >= 0 的时候就是完全背包了。

    另外,当两个价格相同的时候取水的重量更大的一个,这是两个里面都有的一个更新dpw[j]的一个判断。

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    const int N = 1e4+20;
    struct date {
    	int w;
    	int v;
    }a[N];
    int dpv[N], dpw[N];
    int main()
    {
    	int n, m;
    	while(scanf("%d%d", &n, &m)!=EOF) {
    		for(int i=0; i<n; i++)
    			scanf("%d%d", &a[i].v, &a[i].w);
    		memset(dpv, 0x3f, sizeof(dpv));
    		memset(dpw, 0, sizeof(dpw));
    		dpv[0]=0;
    		for(int i=0; i<n; i++) {
    			for(int j=1; j<=m; j++) {
    				if(j-a[i].w < 0) {
    					if(dpv[j] == a[i].v)
    						dpw[j] = max(dpw[j], a[i].w);
    					else if(dpv[j] > a[i].v) {
    						dpv[j] = a[i].v;
    						dpw[j] = a[i].w;
    					}
    				}
    				else {
    					if(dpv[j] == dpv[j-a[i].w] + a[i].v)
    						dpw[j] = max(dpw[j], dpw[j-a[i].w] + a[i].w);
    					else if(dpv[j] > dpv[j-a[i].w] + a[i].v) {
    						dpv[j] = dpv[j-a[i].w] + a[i].v;
    						dpw[j] = dpw[j-a[i].w] + a[i].w;
    					}
    				}
    			}
    		}
    		printf("%d %d
    ", dpv[m], dpw[m]);	
    	}
    	return 0;
    } 
  • 相关阅读:
    [转载]MATLAB 图像处理命令
    html Window与document区别(轉)
    ICMP数据包结构(转)
    CString,string,char*之间的转换(转)
    word或dword区别
    VS2010 皮肤扩展
    Unicode _T和L和_TXET
    转:git 的常用命令
    git fetch 和 git pull 的区别
    mac git 命令自动补全
  • 原文地址:https://www.cnblogs.com/zyq1758043090/p/11852499.html
Copyright © 2020-2023  润新知