P1164 小A点菜

题目描述:ios

这是一道对于大佬来讲很简单的dp题目,之前原本想作来着,结果由于不会dp因此就直接放弃了,昨天又看到这道题准备把他作了,但是不会dp怎么办啊/最后我求助了lixx大佬帮我梳理了一下思路,而后今天又作了很久,把这道题AC了/不过说实话想通了以后这道题还真不难,可是我作dp的时候一般都想不通qwq。数组

接下来大佬能够自行跳过吼吼吼(๑•̀ㅂ•́)و✧spa

 

首先咱们把hh[i][j]设为前i道菜、有j元,这样状况下的点菜方法(总感受好像说的很不清楚,但是个人表达能力也就这样了,实在抱歉code

那么咱们能够来模拟一下可能会遇到的状况:买与不买,而买的话又分为两种状况:1.如今的钱恰好能够买一道当前这样的菜。2.如今的钱买完这样的菜以后还剩下一些钱。blog

咱们先来解决不买这种状况,由于不买他只有一种状况比较简单嘛,其实咱们只要添加一句话就行了:继承

hh[i][j]=hh[i-1][j];//继承上一道菜j元时的点菜方法

若是他不买的话就直接继承上一道菜j元时的方法就好了。而他若是买的话也须要继承,只不过还要加一些多出来的方案数,因此咱们直接添加这一句连判断都省了,要买咱们就能够直接添加多出来的方案数。io

可能会有同窗不知道为何要继承上一道菜j元时的方法(会不会有呢?我也不晓得偶),咱们直接继承就表明咱们不买这道菜,不买这道菜方案数就不会增多,因此直接继承就好喽。class

而后接下来咱们来解决第二种状况:买。这种状况可就不能只是一句话了,毕竟他还要加多出来的方案数,可是其实也不难,两个判断就完事:stream

if(j==a[i]) hh[i][j]++;//判断若是如今的钱恰好买第i道菜,刚才咱们已经继承了上一个的方案数,因此咱们如今只用在刚才的基础上+1就好了。
else if(j>a[i]) hh[i][j]+=hh[i-1][j-a[i]];//判断若是如今的钱买完第i道菜还剩下了钱,那么咱们再在刚才的基础上加上剩下的钱能买菜的方案数

可能你们又会疑惑,为何只要i-1的值而不要i-二、i-三、i-4......的值呢?基础

由于i-1的值是当前最准确的值,你想啊,若是i-1的时候恰好又增长了方案数,那你加i-2或者更小的值就会恰好错过这个方案数。仍是那句话,i-1的值是当前最准确的了。

而后应该没有什么疑问了伐(至少我想不到了

那么最后放一个完整代码:

#include<iostream>
#include<cstdio>
using namespace std;
int n,m,a[1100],hh[1100][1100];//数组必定要开1000,我一开始开了100WA了两个点
int main(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }//以上为输入
    for(int i=1;i<=n;i++){//开始dp循环
        for(int j=1;j<=m;j++){
            hh[i][j]=hh[i-1][j];
            if(j==a[i]) hh[i][j]++;
            else if(j>a[i]) hh[i][j]+=hh[i-1][j-a[i]];
                        //上面的我都在以前讲过了,看不懂就怪你喽略略略
                    }
    }
    printf("%d\n",hh[n][m]);//输出
    return 0;
}

 

以上仅是我的对于这道题的所有思路与想法,若是有什么不对的地方,还请各位大佬及时向我纠正。

相关文章
相关标签/搜索