[洛谷P1658]购物

来源:互联网 发布:离婚率 知乎 编辑:程序博客网 时间:2024/05/22 14:21

题目←

因为看方法大概跟题解里的不太一样,就另写了个题解丢上去了
这里就不再写了……

#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;}
原创粉丝点击