因为看方法大概跟题解里的不太一样,就另写了个题解丢上去了
这里就不再写了……
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int x,n,v[10010],cnt;
int dp[10010],ans = 10010;
bool exist[10010];
int check(){
memset(dp,0x3f,sizeof(dp));
dp[0] = 0,dp[1] = 1;
for(int i = 1;i <= x*2;i ++){
for(int j = 1;j <= n;j ++){
if(i - v[j] >= 0 && v[j] <= i - v[j] + 1)
dp[i] = min(dp[i],dp[i - v[j]] + 1);
}
if(i >= x)ans = min(ans,dp[i]);
}
return ans;
}
int main(){
scanf("%d%d",&x,&n);
for(int i = 1;i <= n;i ++){
scanf("%d",&v[i]);
exist[v[i]] = true;
}
if(!exist[1])printf("-1");
else printf("%d",check());
return 0;
}
题解里给出的正解是贪心
第二篇解释的相当不错,这里就不再说了
因为从大往小挑能放则放,所以第一个到达答案的一定是最优解
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int x,n,v[10010],cnt;
int dp[10010],ans;
bool exist[10010];
bool cmp(int a,int b){
return a > b;
}
int tot,p;
int main(){
scanf("%d%d",&x,&n);
for(int i = 1;i <= n;i ++){
scanf("%d",&v[i]);
}
sort(v + 1,v + n + 1,cmp);
if(v[n] != 1){
printf("-1");
return 0;
}
while(true){
if(tot >= x){
printf("%d",ans);
return 0;
}
for(p = 1;p <= n;p ++)
if(v[p] <= tot + 1){
tot += v[p];
ans ++;
break;
}
}
return 0;
}