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
  • 相关阅读:
    selectHelper
    Windows Server 2003 下实现网络负载均衡(2) (转)
    顺序栈
    线性表链式存储
    线性表顺序存储
    Swift
    组件化
    swift
    Swift
    Swift
  • 原文地址:https://www.cnblogs.com/orangeko/p/12249754.html
Copyright © 2011-2022 走看看