zoukankan      html  css  js  c++  java
  • noj 1413 Weight 宁波 (dp)

      • http://ac.nbutoj.com/Problem/view.xhtml?id=1413
      • [1413] Weight

      • 时间限制: 1000 ms 内存限制: 65535 K
      • 问题描述
      • 有n个砝码,每个砝码都有各自的重量。
        那么这些砝码一共能称出哪些重量。
      • 输入
      • 输入一个正整数 n (1 <= n <= 100)表示一共有 n 个砝码。
        接下来一行有n个正整数,每个正整数表示该砝码的重量,其重量不会超过100。
      • 输出
      • 从小到大输出所有可能的情况。
        对于每行,包含两个数,前面一个数是能称出的重量,后面一个数是能称出该重量的不同情况的数量(就算重量相等的砝码也被视为不同的砝码)。
        其数量要对100000007求余。
      • 样例输入
      • 4
        1 2 3 4
        
      • 样例输出
      • 1 1
        2 1
        3 2
        4 2
        5 2
        6 2
        7 2
        8 1
        9 1
        10 1
      • 题解:

    对于样例输入:

    1  -->    1

    2  -->    2    3

    3  -->    3    4     5     6

    4  -->    4    5     6     7     7     8     9     10 

    对于第N次遍历,就是第N个数与前N-1行分别相加的结果,还有不要忘了N本身也得算一次

    不难得到dp方程:  dp[a[i]+j]+=dp[j],当dp[j]!=0时;

    代码:C++

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<math.h>
     4 #include<algorithm>
     5 #include<string.h>
     6 #include<string>
     7 #include<ctime>
     8 #include<queue>
     9 #include<list>
    10 #include<map>
    11 #include<set>
    12 #include<vector>
    13 #include<stack>
    14 #define INF 999999999
    15 #define MAXN 10000000
    16 using namespace std;
    17 int dp[10010];
    18 int main()
    19 {
    20     int n;
    21     while(~scanf("%d",&n))
    22     {
    23         int i,j,a[110];
    24         memset(dp,0,sizeof(dp));
    25         for(i=1;i<=n;i++)
    26             scanf("%d",&a[i]);
    27         int s=0;
    28         for(i=1;i<=n;i++)
    29         {
    30             s+=a[i];          //前i个值之和,也就是j遍历开始的最大值
    31             for(j=s-a[i];j>0;j--)   //这里必须是反过来的遍历,因为后面的遍历可能改变前面已经遍历过的值,不信可以debug试试
    32             {
    33                 if(dp[j])
    34                 {
    35                     dp[j+a[i]]+=dp[j];
    36                     dp[j+a[i]]%=100000007;
    37                 }
    38             }
    39             dp[a[i]]++;    //将本身的情况加进去
    40             dp[a[i]]%=100000007;
    41         }
    42         for(i=1;i<=s;i++)
    43             if(dp[i])
    44             {
    45                 printf("%d %d\n",i,dp[i]);
    46             }
    47     }
    48     return 0;
    49 }
  • 相关阅读:
    常用源代码管理工具与开发工具
    项目发布
    学期总结
    个人博客
    个人博客
    阅读笔记6
    阅读笔记5
    阅读笔记4
    团队代码
    团队代码
  • 原文地址:https://www.cnblogs.com/crazyapple/p/3015069.html
Copyright © 2011-2022 走看看