小苯的Polygon

题目链接:https://ac.nowcoder.com/acm/contest/104637/E

题意:

在给定的数组中选出一些数,组成封闭凸多边形周长最小

思路:

注意到:最长边<其他所有边之和

不妨枚举最长边,再对小于它的边进行背包dp,以此来求解

dp数组的0/1状态分别表示:其他边(总长为j)此时可以转移得到

背包初始化dp[0]=1,枚举其他边总长(big+1,1e4),如果dp[j]=1,即可以通过01背包得到,立刻取min并break

从后往前枚举,发现dp[p]可以由dp[p-a[i]]转移得到,即如果dp[p-a[i]]可以得到,那么dp[p]也可以得到

void solve(){
	int n;cin>>n;
	vector<int>a(n+1);
	for(int i=1;i<=n;i++)cin>>a[i];
	sort(a.begin()+1,a.end());
	vector<int>dp(maxn);
	dp[0]=1;
	
	int ans=1e9;
	
	for(int i=1;i<=n;i++){
		int big=a[i];
		
		for(int j=big+1;j<=1e4;j++){
			if(dp[j]){
				ans=min(ans,j+big);break;
			}
		}
		
		for(int p=1e4;p>=big;p--){
			dp[p]|=dp[p-a[i]];
		}	
		
	}
	if(ans>1e8)cout<<-1<<endl;
	else cout<<ans<<endl;
}
posted @ 2025-03-24 16:36  Marinaco  阅读(16)  评论(0)    收藏  举报
//雪花飘落效果