【NOIP1999】邮票面值设计 dfs+dp

题目传送门

这道题其实就是找一波上界比较麻烦 用一波 背包可以推出上界mx 所以新加入的物品价值一旦大于mx+1,显然就会出现断层,所以可以以maxm+1为枚举上界,然后这样进行下一层的dfs。

这样就愉快的解决问题了 23333

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int M=505;
int read(){
    int ans=0,f=1,c=getchar();
    while(c<'0'||c>'9'){if(c=='-') f=-1; c=getchar();}
    while(c>='0'&&c<='9'){ans=ans*10+(c-'0'); c=getchar();}
    return ans*f;
}
int n,m,ans;
int w[M],sum[M],f[M+7];
void dfs(int deep){
    int mx;
    memset(f,0x3f,sizeof(f));
    f[0]=0;
    for(mx=1;mx<=M;mx++){
        for(int i=1;i<=deep&&w[i]<=mx;i++) f[mx]=min(f[mx],f[mx-w[i]]+1);
        if(f[mx]>n){
            mx--;
            if(mx>ans){
                ans=mx;
                for(int i=1;i<=deep;i++) sum[i]=w[i];
            }
            break;
        }
    }
    if(deep==m) return ;
    for(int i=mx+1;i>w[deep];i--){
        w[deep+1]=i;
        dfs(deep+1);
    }
}
int main()
{
    n=read(); m=read();
    w[1]=1;
    dfs(1);
    for(int i=1;i<=m;i++) printf("%d ",sum[i]); 
    printf("\n");
    printf("MAX=%d\n",ans);
    return 0;
}
View Code

 

posted @ 2017-07-03 21:38  友人Aqwq  阅读(338)  评论(0编辑  收藏  举报