依赖背包TLE3个点求助
查看原帖
依赖背包TLE3个点求助
383781
UT_MC_wuming楼主2024/7/21 16:35

rt,#7,8,9TLE了其他AC

#include <bits/stdc++.h>
using namespace std;
const int maxx=32005;
typedef int ll;
ll T,M,c[65],va[65],dp[maxx]={},w[65];//c花费,v重要度,w所求乘积
//dp[k]表示前k组最优解
vector<ll>vice[65],chief;//分组
bool vis[65];
ll dp1[61][maxx]={};
int limit[65]; 
int main() {
	scanf("%d%d",&T,&M);
	int p=0;
	for(int i=1; i<=M; i++) {
		scanf("%d%d%d",&c[i],&va[i],&p);
		w[i]=c[i]*va[i];
		if(p!=0)vice[p].push_back(i);
		else {
			chief.push_back(i);
			vis[i]=true;
		}
	}
	//先把有副的以主为根跑一遍01背包
	//分组并将每一组转化为(V-c[i]+1)个物品的物品组
	int si=chief.size();
	//cout<<chief[0]<<endl;
	for(int i=0; i<si; i++) {
		int tem=chief[i];
		for(int j=c[tem]; j<=T; j++)dp1[tem][j]=w[tem]; //主机每组都必须买(主机cost在分组计算时+)
		/*if(vice[tem].empty()){
			limit[tem]=	
		}*/
		for(int j=0; j<vice[tem].size(); j++) {//枚举每种附件 
			for(int k=T;k>=c[vice[tem][j]]+c[tem];k--){
				dp1[tem][k]=max(dp1[tem][k],dp1[tem][k-c[vice[tem][j]]]+w[vice[tem][j]]);
			}

		}
	}
	/*for(int i=1;i<=M;i++){
		for(int j=0;j<T;j++){
			cout<<dp1[i][j]<<" ";
		}cout<<endl;
	}*/
	//再以每个主及副为一组
	for(int k=1; k<=M; k++) {
		if(vis[k]) {//为主件 
			//int tem=chief[k];nb
			for(int v=T; v>=c[k]; v--) {
				//if(!vice[k].empty()) {
					for(int i=v; i>=c[k]; i--) {
						dp[v]=max(dp[v],dp[v-i]+dp1[k][i]);
						//if(dp1[k][i]==c[k])break;剪枝,但交上去又多一个TLE)因为break之前114514次循环都要判断的) 
						
					}//cout<<k<<" "<<dp[T]<<endl;
				//}
			}
		}
	}printf("%d",dp[T]);
	return 0;
}

没看题解自己打的

一开始没看到说附件<=2个所以写复杂了

有大佬能来降下时间复杂度吗谢谢

2024/7/21 16:35
加载中...