UVA - 10280 Old Wine Into New Bottles

来源:互联网 发布:ismo软件 编辑:程序博客网 时间:2024/05/23 19:49

首先觉得总容量很大,瓶子种类很多,直接完全背包肯定不行。但是既然数据大的离谱,肯定有别的方法可以降低复杂度。我的大致思路对了,就是找到完全背包的上界,但是在具体实现上碰到了一些问题,包括最后对复杂度还是没有自信。

两个方面,一个是完全背包上界:maxx=min(maxx,s[i][0]*s[i][0]/(s[i][1]-s[i][0]));

另一方面是粗算瓶子种类有180*100=18000种,但细算实际上最多4500种,这里没想到让我一直tle

#include<cstdio>#include<cstring>#include<algorithm>#include<iostream>#define MAXN 110#define MAXM 4505using namespace std;int s[MAXN][2],l,n,maxx;int dp[MAXN*MAXM],bottle[MAXM],maxbottle,lastbottle[MAXM];void init(){cin>>l>>n;maxx=0x7f7f7f7f;int all=0;for(int i=0;i<n;i++){cin>>s[i][0]>>s[i][1];all+=s[i][1]-s[i][0];maxx=min(maxx,s[i][0]*s[i][0]/(s[i][1]-s[i][0]));}maxx=maxx+10;memset(dp,0,sizeof(dp));dp[0]=1;memset(bottle,0,sizeof(bottle));}void solve(){if(l*1000<maxx){for(int i=0;i<n;i++){for(int j=s[i][0];j<=s[i][1];j++){bottle[j]=1;}}maxbottle=0;for(int i=0;i<MAXM;i++){if(bottle[i])lastbottle[maxbottle++]=i;}for(int i=0;i<maxbottle;i++){for(int j=lastbottle[i];j<maxx&&j<=l*1000;j++){dp[j]|=dp[j-lastbottle[i]];}}for(int i=l*1000;i>=0;i--){if(dp[i]){cout<<l*1000-i<<endl;break;}}}else{cout<<0<<endl;}}int main(){int T;cin>>T;while(T--){init();solve();if(T)cout<<endl;}return 0;}


0 0