首页 > 代码库 > 【NOIP1999】邮票面值设计 dfs+dp

【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

 

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