关于顺推的一种做法
查看原帖
关于顺推的一种做法
764011
LoveMe_楼主2023/6/1 23:59

我自己没看题解写的顺推,没有wa但是有2、 8两个TLE,其余都是ac

#include<iostream>
#include<cstdio>
#include<iomanip>
using namespace std;
int n,k;
int p[20],s[20];
double f[1<<17][102];
double dp(int d,double val,int stat){
	if(d>k)return val;
	if(f[stat][d])return f[stat][d]+val;
//	if(stat+stat2==((1<<n)-1)){
//		double ans = val; 
//		for(int i = 1;i<=n;i++){
//			if((s[i]&stat)==s[i])ans+=p[i]*(k-d+1)/n;
//		}
//		return ans;  
//	}
	double ans = 0;
	for(int i = 1;i<=n;i++){
	//	printf("-%d %d %d\n",s[i],stat,s[i]&stat);
		if((s[i]&stat)==s[i]){
		//	cout << 22222;
			if(p[i]>=0){
				ans+=dp(d+1,val+p[i],stat|(1<<(i-1)));
			}else{
				double a1,a2;
				a1 = dp(d+1,val+p[i],stat|(1<<(i-1)));
				a2 = dp(d+1,val,stat);
				if(a1>a2)ans += a1;
				else ans += a2;
			}
			
			
		}else{//不能选i
			ans += dp(d+1,val,stat);
		}
			
	
	}
	ans/=n;
	f[stat][d] = ans-val;
	return ans;
}
int main(){
 
	scanf("%d%d",&k,&n);
	for(int i = 1;i<=n;i++){
		scanf("%d",&p[i]);
		int temp;
		scanf("%d",&temp);   
		while(temp){
			s[i]+=1<<(temp-1);
			scanf("%d",&temp);
		}
	//	cout <<'-'<< s[i]<< endl;
	}
	cout << fixed<< setprecision(6)<<dp(1,0,0);
	return 0;
} 

注释掉的代码不用管,stat指的就是之前已经选择过的宝物集合 我觉得再改改应该没问题,我8个过了的数据点都很快,就是只有那俩数据点tle,我估计是哪里死循环了

2023/6/1 23:59
加载中...