Code Forces 189A - Cut Ribbon 暴力||DP

来源:互联网 发布:淘宝店基本常识 编辑:程序博客网 时间:2024/06/01 10:28

对一根长度为n绳子进行分割,要求分割后每段的长度只能是a,b,c中的一个

求能分成的最多的段数(保证有解)

思路一 

完全背包 装满背包的最多选择的物品数

dp[i]表示长度为i的绳子最多可以分割成的段数

状态转移方程 dp[i]=max(dp[i],dp[i-x]+1);x为a或者b或者c

因为要求是装满,就是不能有剩余,所以初始化dp的时候除了dp[0]都初始化成负值,这样当dp[i-x]>=0的时候才能转移,可以保证装满。

#include<stdio.h>#include<string.h>#define max(a,b) a>b?a:bint main(){    int dp[4001];    int n,a,b,c;    while(scanf("%d %d %d %d",&n,&a,&b,&c)!=EOF){        memset(dp,-1,sizeof(dp));        dp[0]=0;        int mx=0;        for(int i=1;i<=n;i++){            if(i>=a&&dp[i-a]>=0)dp[i]=max(dp[i-a]+1,dp[i]);            if(i>=b&&dp[i-b]>=0)dp[i]=max(dp[i-b]+1,dp[i]);            if(i>=c&&dp[i-c]>=0)dp[i]=max(dp[i-c]+1,dp[i]);        }        printf("%d\n",dp[n]);    }    return 0;}


思路二

暴力枚举.

a最多可以选择n/a个,剩余体积now=n-i*a

然后b最多可以选择now/b,剩余体积n-i*a-i*b

如果剩余体积可以被c整除,说明这个方案可以无剩余地切割,此时段数为i+j+(n-i*a-j*b)/c,

每找到一个合法的方案,更新最大值即可。

#include<stdio.h>#define max(a,b) a>b?a:bint main(){    int n,a,b,c;    while(scanf("%d %d %d %d",&n,&a,&b,&c)!=EOF){        int mx=0;        for(int i=0;i<=n/a;i++){            int now=n-i*a;            for(int j=0;j<=now/b;j++){                if((n-i*a-j*b)%c==0)                    mx=max(mx,i+j+(n-i*a-j*b)/c);            }        }        printf("%d\n",mx);    }    return 0;}



原创粉丝点击