本题乍一看像完全背包问题,但是仔细分析可以看出其实是一道bfs。bfs的状态即为当前买的糖数,从0搜索到m。要注意的是超过m的状态需要剪枝,否则容易越界。
时间复杂度为
空间复杂度为
以下是AC代码:
#define maxm 10005
class Solution {
public:
/**
* 返回最少需要买的糖包数
* @param n int整型 表示共有多少种糖包
* @param m int整型 表示一共需要买的糖数
* @param num int整型一维数组 表示每种糖包所含的糖的数量
* @param numLen int num数组长度
* @return int整型
*/
int solve(int n, int m, int* num, int numLen) {
int dis[maxm];
memset(dis,0,sizeof(dis));//初始设置为0,既用来标记,也用来保存答案
queue<int> q;
q.push(0);//初始状态为0
while(!q.empty())
{
int t=q.front();
if(t==m)
break;
q.pop();
for(int i=0;i<n;i++)
{
int w=num[i]+t;
if(w<=m&&!dis[w])//w超过m不予考虑,dis[w]为0表示没有访问过该状态
{
dis[w]=dis[t]+1;
q.push(w);
}
}
}
return dis[m];
}
};另外,暴力也可以做本题,但是本质上和bfs的做法是相同的,并且代码量和bfs相当。
时间复杂度为
空间复杂度为
#define maxm 10005
class Solution {
public:
/**
* 返回最少需要买的糖包数
* @param n int整型 表示共有多少种糖包
* @param m int整型 表示一共需要买的糖数
* @param num int整型一维数组 表示每种糖包所含的糖的数量
* @param numLen int num数组长度
* @return int整型
*/
int solve(int n, int m, int* num, int numLen) {
int book[maxm];
memset(book,0,sizeof(book));
int ans=0;
vector<int> vec[maxm];
vec[0].push_back(0);
while(!book[m])
{
for(int i=0;i<vec[ans].size();i++)
{
int u=vec[ans][i];
for(int j=0;j<n;j++)
{
if(u+num[j]<=m&&book[u+num[j]]==0)
{
book[u+num[j]]=1;
vec[ans+1].push_back(u+num[j]);
}
}
}
ans++;
}
return ans;
}
};
京公网安备 11010502036488号