zoukankan      html  css  js  c++  java
  • P1164 小A点菜【dp】

    P1164 小A点菜

    提交 43.03k
    通过 24.37k
    时间限制 1.00s
    内存限制 125.00MB
    题目提供者 洛谷
    难度 普及-
    历史分数100

    提交记录

    标签

     
    查看算法标签
    进入讨论版

    相关讨论

     
    查看讨论

    推荐题目

     
    查看推荐
     

    展开

    题目背景

    uim神犇拿到了uoira(镭牌)后,立刻拉着基友小A到了一家……餐馆,很低端的那种。

    uim指着墙上的价目表(太低级了没有菜单),说:“随便点”。

    题目描述

    不过uim由于买了一些辅(e)辅(ro)书,口袋里只剩MMM元(M≤10000)(M le 10000)(M10000)。

    餐馆虽低端,但是菜品种类不少,有NNN种(N≤100)(N le 100)(N100),第iii种卖aia_iai(ai≤1000)(a_i le 1000)(ai1000)。由于是很低端的餐馆,所以每种菜只有一份。

    小A奉行“不把钱吃光不罢休”,所以他点单一定刚好吧uim身上所有钱花完。他想知道有多少种点菜方法。

    由于小A肚子太饿,所以最多只能等待111秒。

    输入格式

    第一行是两个数字,表示NM

    第二行起N个正数ai(可以有相同的数字,每个数字均在1000以内)。

    输出格式

    一个正整数,表示点菜方案数,保证答案的范围在int之内。

    输入输出样例

    输入 #1
    4 4
    1 1 2 2
    
    输出 #1
    3

    思路:
      用f[i][j]来表示取到第i个物品、有j块钱能吃到的方案数。
      在每次转移时,有三种情况:
      1、j == w[i], 此时f[i][j]等于选了i-1件的有j块钱的方案数+1.
      2、j > w[i], 此时由于钱是富足的,所以可以拿f[i-1][j]+f[i-1][j-w[i]]的方案数
      3、j < w[i], 此时由于钱不够了,所以拿不了,方案数为f[i-1][j].

      因为和上一个物品状态关联不大。题解把三个情况总结到一起了,方程写成了f[j-w[i]],在nm比较大的时候可以用上。

     1 #include <bits/stdc++.h>
     2 #define dbg(x) cout << #x << "=" << x << endl
     3 
     4 using namespace std;
     5 typedef long long LL;
     6 const int maxn = 100 + 7;
     7 
     8 int f[maxn][10007];
     9 int w[maxn];
    10 
    11 namespace _buff {
    12 
    13 const size_t BUFF = 1 << 19;
    14 char ibuf[BUFF], *ib = ibuf, *ie = ibuf;
    15 char getc() {
    16     if (ib == ie) {
    17         ib = ibuf;
    18         ie = ibuf + fread(ibuf, 1, BUFF, stdin);
    19     }
    20     return ib == ie ? -1 : *ib++;
    21 }
    22 
    23 }
    24 
    25 int read() {
    26     using namespace _buff;
    27     int ret = 0;
    28     bool pos = true;
    29     char c = getc();
    30     for (; (c < '0' || c > '9') && c != '-'; c = getc()) {
    31         assert(~c);
    32     }
    33     if (c == '-') {
    34         pos = false;
    35         c = getc();
    36     }
    37     for (; c >= '0' && c <= '9'; c = getc()) {
    38         ret = (ret << 3) + (ret << 1) + (c ^ 48);
    39     }
    40     return pos ? ret : -ret;
    41 }
    42 
    43 int main()
    44 {
    45     int n,m;
    46     scanf("%d %d",&n,&m);
    47     for(int i = 1; i <= n; ++i) {
    48         scanf("%d",&w[i]);
    49     }
    50     int ans = 0;
    51     for(int i = 1; i <= n; i++) {
    52         for(int j = 0; j <= m; j++) {
    53             if(j == w[i]) {
    54                 f[i][j] = f[i-1][j] + 1;
    55             }
    56             else if(j > w[i]) {
    57                 f[i][j] = f[i-1][j] + f[i-1][j-w[i]];
    58             }
    59             else if(j < w[i]) {
    60                 f[i][j] = f[i-1][j];
    61             }
    62         }
    63     }
    64 
    65     printf("%d
    ",f[n][m]);
    66     return 0;
    67 }
    View Code
  • 相关阅读:
    A1066 Root of AVL Tree (25 分)
    A1099 Build A Binary Search Tree (30 分)
    A1043 Is It a Binary Search Tree (25 分) ——PA, 24/25, 先记录思路
    A1079; A1090; A1004:一般树遍历
    A1053 Path of Equal Weight (30 分)
    A1086 Tree Traversals Again (25 分)
    A1020 Tree Traversals (25 分)
    A1091 Acute Stroke (30 分)
    A1103 Integer Factorization (30 分)
    A1032 Sharing (25 分)
  • 原文地址:https://www.cnblogs.com/orangeko/p/12249754.html
Copyright © 2011-2022 走看看