• DP URAL 1244 Gentlemen


    题目传送门

     1 /*
     2     题意:已知丢失若干卡片后剩余的总体积,并知道原来所有卡片的各自的体积,问丢失的卡片的id
     3     DP递推:首先从丢失的卡片的总体积考虑,dp[i] 代表体积为i的方案数,从dp[0] = 1递推,累加的条件是dp[j]上一个状态已经有方案,
     4             若dp[w] > 1表示有多种方案,外加p[j+a[i]] = i的记录路径数组
     5     我开始用了暴力DFS超时,dp不会写,看了题解发现是个递推,有点像01背包的题目:)
     6     详细解释:http://blog.csdn.net/neko01/article/details/10033787
     7 */
     8 #include <cstdio>
     9 #include <iostream>
    10 #include <algorithm>
    11 #include <cstring>
    12 #include <string>
    13 #include <cmath>
    14 using namespace std;
    15 
    16 const int MAXN = 1e2 + 10;
    17 const int MAXM = 1e6 + 10;
    18 const int INF = 0x3f3f3f3f;
    19 int a[MAXN];
    20 int p[MAXM];
    21 int ans[MAXN];
    22 int dp[MAXM];
    23 
    24 int main(void)        //URAL 1244 Gentlemen
    25 {
    26     //freopen ("L.in", "r", stdin);
    27 
    28     int w, n, sum;
    29     while (scanf ("%d", &w) == 1)
    30     {
    31         sum = 0;
    32         scanf ("%d", &n);
    33         for (int i=1; i<=n; ++i)
    34         {
    35             scanf ("%d", &a[i]);    sum += a[i];
    36         }
    37         
    38         memset (p, 0, sizeof (p));
    39         memset (dp, 0, sizeof (dp));
    40         dp[0] = 1;    w = sum - w;
    41 
    42         for (int i=1; i<=n; ++i)
    43         {
    44             for (int j=w-a[i]; j>=0; --j)
    45             {
    46                 if (dp[j])
    47                 {
    48                     if (!dp[j+a[i]])    p[j+a[i]] = i;
    49                     dp[j+a[i]] += dp[j];
    50                 }
    51             }
    52         }
    53 
    54         int cnt = 0;
    55         if (dp[w] == 0)    puts ("0");
    56         else if (dp[w] == 1)
    57         {
    58             for (int i=n; i>=1; --i)
    59             {
    60                 if (p[w] == i)
    61                 {
    62                     ans[++cnt] = i;
    63                     w -= a[i];
    64                 }
    65             }
    66 
    67             for (int i=cnt; i>=1; --i)
    68             {
    69                 printf ("%d%c", ans[i], (i==1) ? '
    ' : ' ');
    70             }
    71         }
    72         else    puts ("-1");
    73     }
    74 
    75     return 0;
    76 }
    编译人生,运行世界!
  • 相关阅读:
    Java 图片处理——如何生成高清晰度而占有磁盘小的缩略图
    【设计模式】状态模式
    【设计模式】策略模式
    【设计模式】迭代器模式
    【设计模式】观察者模式
    【设计模式】享元模式
    【设计模式】桥接模式
    【设计模式】组合模式
    【设计模式】外观模式
    【设计模式】代理模式
  • 原文地址:https://www.cnblogs.com/Running-Time/p/4390924.html
Copyright © 2020-2023  润新知