zoukankan      html  css  js  c++  java
  • hdu6092(dp)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6092

    题意: 输入格式为, 对于每组测试样例第一行输入两个数 n, m, 接下来一行输入B数组, 有 m + 1个数. 其中 n 表示要构造的数组 A 的长度为 n. m 表示 A 数组的元素和为 m. 第二行的m + 1 个数字表示 A 数组 有子集中和为 0, 1, ..., m 的子集个数.

    思路: 可以从 1 到 m 依次确定每个数出现的次数. 用 dp[i] 表示当前答案集中和为 i 的子集数.

    枚举 1 <= i <= m, 对于当前 i, 其在 A 中出现的次数为 B[i] - dp[i], 每往 A 中添加一个元素更新一次 dp 数组.

    更新 dp 的过程可以看作一个 01 背包过程.

    代码:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <string.h>
     4 using namespace std;
     5 
     6 const int MAXN = 1e4 + 10;
     7 int dp[MAXN], a[MAXN], sol[MAXN];//dp[i]存储当前答案集中和为i的子集有多少
     8 
     9 int main(void){
    10     int t, n, k;
    11     scanf("%d", &t);
    12     while(t--){
    13         int indx = 0;
    14         memset(dp, 0, sizeof(dp));
    15         scanf("%d%d", &n, &k);
    16         for(int i = 0; i <= k; i++){
    17             scanf("%d", &a[i]);
    18         }
    19         dp[0] = 1;
    20         for(int i = 1; i <= k; i++){
    21             int cnt = a[i] - dp[i];
    22             for(int j = 0; j < cnt; j++){
    23                 sol[indx++] = i;
    24                 for(int l = k; l >= i; l--){//注意先更新小的数会影响后面的更新
    25                     dp[l] += dp[l - i];
    26                 }
    27             }
    28         }
    29         for(int i = 0; i < indx; i++){
    30             if(i) printf(" ");
    31             printf("%d", sol[i]);
    32         }
    33         puts("");
    34     }
    35     return 0;
    36 }
    View Code
  • 相关阅读:
    动态规划算法-3
    动态规划算法-2
    动态规划算法-1
    滑动窗口算法-3
    央行副行长提示金融风险:地方偿债高峰期到来
    银行卡换“芯” 更要银行换心
    破解IT运维成本困境,专业化分工是妙方
    php连接mysql
    ajax原生验证用户名是否存在
    ajax跨域问题
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/7325996.html
Copyright © 2011-2022 走看看