http://www.yyycode.cn/index.php/2020/05/23/a-cut-ribbon/
https://codeforces.com/problemset/problem/189/A
Polycarpus has a ribbon, its length is n. He wants to cut the ribbon in a way that fulfils the following two conditions:
Help Polycarpus and find the number of ribbon pieces after the required cutting.Input
The first line contains four space-separated integers n, a, b and c (1 ≤ n, a, b, c ≤ 4000) — the length of the original ribbon and the acceptable lengths of the ribbon pieces after the cutting, correspondingly. The numbers a, b and c can coincide.Output
Print a single number — the maximum possible number of ribbon pieces. It is guaranteed that at least one correct ribbon cutting exists.ExamplesinputCopy
5 5 3 2
outputCopy
2
inputCopy
7 5 5 2
outputCopy
2
Note
In the first example Polycarpus can cut the ribbon in such way: the first piece has length 2, the second piece has length 3.
In the second example Polycarpus can cut the ribbon in such way: the first piece has length 5, the second piece has length 2.
题意:有长度为n的绳子,用长度为a,b,c的小绳子去拼,问用到最多的绳子段数是多少.
思路:做之前看到dp,想到割绳子,但是没想出怎么定义dp状态,于是写了dfs,直接在第5个样例TLE,4000 1 2 3 ;
TLE:
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e5;
typedef long long LL;
LL res;
LL n,a,b,c;
void dfs(LL length,LL sum)//length表示目前枚举到的长度, sum表示绳子数量
{
// cout<<"目前枚举到的长度:"<n) return;
if(length==n)
{
res=max(res,sum);return;
}
dfs(length+a,sum+1);
dfs(length+b,sum+1);
dfs(length+c,sum+1);
}
int main(void)
{
cin>>n>>a>>b>>c;
res=-1;
dfs(0,0);
cout<
然后呢?n^2暴力枚举叭..p*a+k*b+f*c==n,对p,k,进行枚举,f进行判断,就可以过啦
#include
#include
#include
#include
#include
using namespace std;
const int maxn=1e5;
typedef long long LL;
int main(void)
{
LL n,a,b,c;cin>>n>>a>>b>>c;
LL res=-1;
for(LL i=0;i<=n/a;i++)
for(LL j=0;i*a+j*b<=n;j++)
{
if( (n-a*i-b*j )%c==0 )
{
res=max(res,(i+j+(n-(a*i)-(b*j))/c) );
}
}
cout<
但是,这个dp怎么写呢?
对于每个绳子,都有取和不取,并且不做限制,是个完全背包问题.
完全背包的二维是dp[i][j]=max(dp[i-1][j],dp[i][j-v[i]]+w[i]);
然后我搞二维的,大晚上的debug了一小时多还没找出来..
搞一维的叭。注意要初始化-1.为什么呢。因为这个题意是要求背包填满的,不初始化的话填的只是背包的价值最大的。
AC:代码
#include
#include
#include
#include
#include
using namespace std;
const int maxn=4040;
#define LL int
//typedef long long LL;
LL f[maxn];
LL d[maxn];
int main(void)
{
LL n,a,b,c;cin>>n>>a>>b>>c;
d[1]=a;d[2]=b;d[3]=c;
memset(f,-0x3f,sizeof(f));
//for(LL i=1;i<=n;i++) f[i][0]=0;
f[0]=0;
// for(LL j=1;j<=n;j++) f[j][j]=1;
for(LL i=1;i<=3;i++)///前i个物品
for(LL j=d[i];j<=n;j++)///总体积
{
f[j]=max(f[j],f[j-d[i]]+1);
// cout<<"f["<
二维的目前还奇奇怪怪的代码,我以为是memset二维的锅,确实在网上看到有人 说不要用.然后改了for。 这个样例:918 102 1327 1733却输出0…
wa的代码,等待有缘人…
#include
#include
#include
#include
#include
using namespace std;
const int maxn=4040;
#define LL int
//typedef long long LL;
LL f[maxn][maxn];
LL d[maxn];
int main(void)
{
LL n,a,b,c;cin>>n>>a>>b>>c;
d[1]=a;d[2]=b;d[3]=c;
// memset(f,-99,sizeof(f));
for(LL i=1;i<=maxn;i++)
for(LL j=1;j<=maxn;j++)
f[i][j]=-10;
for(LL i=1;i<=n;i++) f[i][0]=0;
f[0][0]=0;
// for(LL j=1;j<=n;j++) f[j][j]=1;
for(LL i=1;i<=3;i++)///前i个物品
for(LL j=d[i];j<=n;j++)///总体积
{
f[i][j]=max(f[i-1][j],f[i][j-d[i]]+1);
// cout<<"f["<