第二周,今天的网络赛让我获感良多,今天做到一道题,可以看出来是一道dp题,刚开始我用了完全背包,然后悲哀的我超时了,不过我当时为了记录一个数据,所以要用三重循环才行,超时必然了,之后我就用了深搜加完全背包,这样顶多算是两重循环,但还是超时了,之后我总结了超时的原因,比如1,2,3三种物品,在深搜和完全背包的结合当中,你可能拿了1,2,但是也可能拿了2,1,于是这就出现了重复,导致代码超时,所以三种物品,最后是以全排列的方式进行,则是n方的结构,导致代码超时,后来看来别人的代码,人家的代码就是1取了多少件,2取了多少件其中取得的条件,相比于我的代码要更省时间,还需要加油,
加油臭咸鱼!!。
附我的代码与ACdalao的代码:
我的:(渣渣)
#include<bits/stdc++.h>
using namespace std;
int n,m;
int dp[100005],ans1=-1;
int minn=-1,jl=999999999;
struct Node
{
int v,c;
}p[10005];
void Dfs(int z)
{
if(z>minn)
{
for(int i=1;i<=n;++i)
{
dp[z-p[i].c]=min(dp[z-p[i].c],dp[z]+p[i].v);
Dfs(z-p[i].c);
}
}
else if(z<=minn)
{
for(int i=1;i<=n;++i)
{
if(z-p[i].c>0)
{
dp[z-p[i].c]=min(dp[z-p[i].c],dp[z]+p[i].v);
Dfs(z-p[i].c);
}
else
{
if(dp[0]>dp[z]+p[i].v)
{dp[0]=dp[z]+p[i].v;ans1=m-z+p[i].c;}
else if(dp[0]==dp[z]+p[i].v)
{
ans1=max(m-z+p[i].c,ans1);
}
}
}
}
return ;
}
int main()
{
while(~scanf("%d%d",&n,&m))
{
ans1=-1;
minn=-1;
memset(dp,0x3f3f3f,sizeof(dp));
for(int i=1;i<=n;++i)
{scanf("%d%d",&p[i].v,&p[i].c);
minn=max(minn,p[i].c);
}
dp[m]=0;
Dfs(m);
printf("%d %d\n",dp[0],ans1);
}
return 0;
}
dalao:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<set>
#include<map>
#define long long ll
#define N 100000
using namespace std;
int n,m,ansa,ansb,maxx;
int a[N],b[N],dp[N];
int main()
{
while(cin>>n>>m){
memset(dp,0x3f,sizeof(dp));
dp[0]=0;
for(int i=1;i<=n;i++) {
cin>>a[i]>>b[i];
maxx=max(maxx,b[i]);
}
for(int i=1;i<=n;i++){
for(int j=0;j<=m+maxx;j++){ //就是这,就是这么简单,我咋就没想到!!!!太菜了
if(j>=b[i]) {
dp[j]=min(dp[j],dp[j-b[i]]+a[i]);
}
}
}
int ans=1000000001;
for(int i=m;i<=m+maxx;i++){
if(dp[i]<=ans){
ansb=i;
ansa=dp[i];
ans=dp[i];
}
}
cout<<ansa<<" "<<ansb<<endl;
}
}