zoukankan      html  css  js  c++  java
  • 新年趣事之打牌(01背包+唯一路径)

    过年的时候,大人们最喜欢的活动,就是打牌了。蒜头君不会打牌,只好坐在一边看着。

    这天,正当一群人打牌打得起劲的时候,突然有人喊道: "这副牌少 了几张!”众人一数,果然是少了。于是这副牌的主人得意地说: "这是一幅特制的牌,我知道整副牌每一张的重量。

    只要我们称一下剩下的牌的总重量,就能知道少了哪些牌了。”大家都觉得这个办法不错,于是称出剩下的牌的总重量,开始计算少了哪些牌。于数据量比较大,过了不久,大家都算得头晕了。

    这时,蒜头君大声说:“你们看我的吧! ”于是他拿出笔记本电脑,编出了一个程序,很快就把缺少的牌找了出来。

    如果是你遇到了这样的情况呢?你能办到同样的事情吗?

    输入格式

    第一行一个整数TotalW,表示剩下的牌的总重量。

    第二行一个整数N(1 < N≤100),示这副牌有多少张。

    接下来N行,每行一个整数Wi(1≤Wi≤1000),示每-张牌的重量。

    输出格式

    如果无解,则输出0;如果有多解,则输出−1;否则,按照升序输出丢失的牌的编号,相邻两个数之间用一个空格隔开。

    提示

    组成的方案数可能很多。

    样例输入1

    270
    4
    100
    110
    170
    200

    样例输出1

    2 4

    样例输入2

    270
    4
    100
    110
    160
    170

    样例输出2

    -1

    样例输入3

    270
    4
    100
    120
    160
    180

    样例输出3

    0

    本题除了考察大家 01 背包记录方案数,还考察大家是否可以把答案记录。 当我们更新 dp[j] 值的时候,需要使用 path[j]记录是谁更新了 dp[j]。最后再递归找回去。

     1 #include <stdio.h>
     2 #include <string.h>
     3 #include <iostream>
     4 #include <string>
     5 #include <math.h>
     6 #include <algorithm>
     7 #include <vector>
     8 #include <stack>
     9 #include <queue>
    10 #include <set>
    11 #include <map>
    12 #include <sstream>
    13 #include <ctime>
    14 const int INF=0x3f3f3f3f;
    15 typedef long long LL;
    16 const int mod=1e9+7;
    17 const double PI = acos(-1);
    18 const double eps =1e-8;
    19 #define Bug cout<<"---------------------"<<endl
    20 const int maxn=1e5+10;
    21 using namespace std;
    22 
    23 int w[105];
    24 int dp[maxn];
    25 int path[maxn];
    26 int n,m,sum;
    27 
    28 void PT(int x)
    29 {
    30     if(x)
    31     {
    32         PT(x-w[path[x]]);
    33         printf(x==(sum-m)?"%d
    ":"%d ",path[x]);
    34     }
    35 }
    36 
    37 int main()
    38 {
    39     #ifdef DEBUG
    40     freopen("sample.txt","r",stdin);
    41     #endif
    42 //    ios_base::sync_with_stdio(false);
    43 //    cin.tie(NULL);
    44     
    45     scanf("%d %d",&m,&n);
    46     for(int i=1;i<=n;i++)
    47     {
    48         scanf("%d",&w[i]);
    49         sum+=w[i];
    50     }
    51     dp[0]=1;
    52     for(int i=1;i<=n;i++)
    53     {
    54         for(int j=sum-m;j>=w[i];j--)
    55         {
    56             dp[j]+=dp[j-w[i]];
    57             if(dp[j]>100) dp[j]=10;
    58             if(!path[j] && dp[j-w[i]]) path[j]=i;
    59         }
    60             
    61     }
    62     if(!dp[sum-m]) printf("0
    ");
    63     else if(dp[sum-m]>1) printf("-1
    ");
    64     else PT(sum-m);
    65     
    66     return 0;
    67 }

    -

  • 相关阅读:
    Vue开源项目库汇总【壮灬哥出品,必为精品】
    nginx配置
    找出判断数据是否有相同的值
    CSS设置文字不能被选中
    js怎么删数组固定的值
    IO流中File文件最常用和直接的用法
    JComboBox实现当前所选项功能和JFrame窗口释放资源的dispose()方法
    java中经常使用的Swing组件总结
    JTextArea利用JScrollpane增加文本域滚轮(滚动条)
    JFrame关闭程序就退出的设置
  • 原文地址:https://www.cnblogs.com/jiamian/p/12219042.html
Copyright © 2011-2022 走看看