Lead of Wisdom(dfs)

Lead of Wisdom(dfs)_第1张图片Lead of Wisdom(dfs)_第2张图片
这道题其实一开始以为是个多重背包dp来着,但是后面我又想了dfs,但是一看时间复杂度50^50。我就以为是个dp。这个就是被时间复杂给误导了方向,题后才知道我之前的分析不对,因为有n个,k种,那么平均每种为n/k个;那么dfs的时间复杂度就是k的(n/k)次方,那么就是求这个函数的最值。
取一个对数+求导就可以求出来最值了,当k==e的时候就是最值,这时候大概在1e8时间复杂度。然后题目给了8秒,完全够了。主要注意的是如何把断续的种类给弄成连续的,这里可以用一个book数组来解决;
AC代码:

#include
using namespace std;
typedef long long ll;
ll book[100];
struct Node{
	ll a,b,c,d;
	Node(ll x,ll y,ll z,ll k){
		a=x;b=y;c=z;d=k;
	}
};
vector<Node> V[100];
ll ans;
ll numm=1;
void dfs(ll s,ll a,ll b,ll c,ll d){
	if(s==numm){
		ll t=(100+a)*(100+b)*(100+c)*(100+d);
		ans=max(ans,t);
		return ; 
	}
	for(ll i=0;i<V[s].size();i++){
		dfs(s+1,a+V[s][i].a,b+V[s][i].b,c+V[s][i].c,d+V[s][i].d);
	}
}
int main(){
	ll T;
	scanf("%lld",&T);
	while(T--){
		ll n,k;
		for(ll i=0;i<=50;i++)V[i].clear();//清理 
		for(ll i=0;i<=50;i++)book[i]=0;
		scanf("%lld %lld",&n,&k);
		numm=1;
		ll t,a,b,c,d;
		for(ll i=1;i<=n;i++){
	    	scanf("%lld %lld %lld %lld %lld",&t,&a,&b,&c,&d);
		     if(!book[t])book[t]=numm++;//为了让种类连续以便dfs 
		     V[book[t]].push_back(Node(a,b,c,d));
	    }
	    dfs(1,0,0,0,0);
	    printf("%lld\n",ans);
	    ans=0;
	}
	return 0;
}

你可能感兴趣的:(dfs)