zoukankan      html  css  js  c++  java
  • dp

    题目

    总时间限制: 1000ms 内存限制: 65536kB
    描述
    设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),要求:计算用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况。

    输入
    一行,包括六个正整数a1,a2,a3,a4,a5,a6,表示1g砝码有a1个,2g砝码有a2个,……,20g砝码有a6个。相邻两个整数之间用单个空格隔开。
    输出
    以“Total=N”的形式输出,其中N为可以称出的不同重量的个数。
    样例输入
    1 1 0 0 0 0
    样例输出
    Total=3
    提示
    样例给出的砝码可以称出1g,2g,3g三种不同的重量。

    分析

    状态转移方程是:dp[i][j] = dp[i-1][j] || dp[i-1][j-w[i]], i表示第i个砝码,意思是把所有砝码排开计数,j表示j重量,dp[i][j]表示使用前i个砝码是否可以称出重量j,1表示可以,0表示不可以。
    然后可以用滚动数组节省空间,dp[j] = 1 ,当dp[j-w[i]] =1。

    代码

    #include <cstdio>
    #include <cstring>
    
    int weight[6] = {1, 2, 3, 5, 10, 20};
    int num[6];
    int dp[1000];
    
    int main(){
        for(int i = 0; i < 6; i++){
            scanf("%d", &num[i]);
        }
        int total = 0;
        for(int i = 0; i < 6; i++){
            total += weight[i] * num[i];
        }
        memset(dp, 0, sizeof(dp));
        dp[0] = 1;
        for(int i = 0; i < 6; i++){
            for(int j = 0; j < num[i]; j++){
                for(int k = total; k >= weight[i]; k --){
                    if(dp[k - weight[i]] == 1)
                        dp[k] = 1;
                }
            }
        }
        int sum = 0;
        for(int i = 1; i <= total; i++){
            if(dp[i] == 1)
                sum++;
        }
        printf("Total=%d
    ", sum);
        return 0;
    }
    
  • 相关阅读:
    多线程中变量的内存分配
    VS2019解决Cannot resolve symbol ' '问题
    排序算法——选择排序
    观察者模式
    c# 之linq——小白入门级
    c# 迭代器
    MySql学习
    rabbitmq安装及简单demo练习
    VMware Workstation 12 PRo密钥
    远程过程调用——RPC
  • 原文地址:https://www.cnblogs.com/zhangyue123/p/12621048.html
Copyright © 2011-2022 走看看