时间限制:1秒
空间限制:32768K
热度指数:19924
算法知识视频讲解
题目描述
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。 可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。如果不能购买恰好n个苹果,小易将不会购买。
输入描述:
输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果
输出描述:
输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1
示例1
输入
20
输出
3
【分析】DP
记dp[i]-购买i个苹果所需的最小袋数。首先均初始化为INF(不能买),然后确定边界(dp[0]=0,dp[6]=1,dp[8]=1)及状态转移方程:
dp[i+per[j]=min(dp[i]+1, dp[i+per[j]]); (per[j]为第j种袋子可装的苹果数)
#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=105;
const int INF=1<<30;
int n;
int per[2]={6,8}; //每袋的苹果数
int dp[maxn]; //dp[i]-购买i个苹果所需的最小袋数
void getAns(int *a)
{
int i,j;
a[0]=0;
for(i=1;i<maxn;i++)
a[i]=INF;
a[per[0]]=a[per[1]]=1;
for(i=6;i<maxn;i++)
{
if(a[i]==INF)
continue;
for(j=0;j<2;j++)
{
if(i+per[j]<maxn)
a[i+per[j]]=min(a[i]+1,a[i+per[j]]);
else if(i+per[j]<maxn)
a[i+per[j]]=min(a[i]+1,a[i+per[j]]);
}
}
}
int main()
{
int i,j,suc;
getAns(dp);
scanf("%d",&n);
dp[n]=(dp[n]==INF)?-1:dp[n];
printf("%d\n",dp[n]);
return 0;
}