【递归】油桶问题dp

时间:2023-03-08 17:06:23

问题 : 【递归】油桶问题

题目描述

楚继光扬扬得意道:“当日华山论剑,先是他用黯然销魂掌破了我的七十二路空明拳,然后我改打降龙十八掌,却不防他伸开食指和中指,竟是六脉神剑,又胜我一筹。可见天下武学彼此克制,武学之道玄之又玄!……哎,谁用炒锅敲我头?”

楚继光的老妈大声骂道:“玩个石头剪刀布都说得这般威风,炒菜没油了,快给我去装!”

“这么凶干嘛?不就吹吹牛嘛。”楚继光边嘟嘟囔囔边走进储藏室,看到储藏室有N个油桶都装
满了油,这N个油桶容积各不相同(容积为整数),楚继光需要M升油(M也为整数),请你不借助任何其他容器,判断能否直接在N桶油中取任意K桶
(1≤K≤N)油,其油的总量正好是M升,如果可以,就输出yes,否则输出no。

输入

第一行为两个整数N,M,第二行为N个整数,即油桶的容积。

输出

输出结果即yes或者no。

样例输入

5 10
1 2 3 1 1

样例输出

no
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn = ;
int n, K, a[maxn];
bool dp[maxn][maxn]; void slove(){
dp[][] = true;
for(int i = ; i < n; i++){
for(int j = ; j <= K; j++){
for(int k = ; k <= && a[i] * k <= j; k++){
dp[i+][j] |=dp[i][j - k * a[i]];
}
}
}
if (dp[n][K]) printf("yes\n");
else printf("no\n");
}
int main()
{
scanf("%d%d", &n, &K);
for(int i = ; i < n; i++){
scanf("%d",&a[i]);
}
slove();
return ;
}