题意:NOI2011 在吉林大学开始啦!为了迎接来自全国各地最优秀的信息学选手,
吉林大学决定举办两场盛大的 NOI 嘉年华活动,分在两个不同的地点举办。每
个嘉年华可能包含很多个活动,而每个活动只能在一个嘉年华中举办。
现在嘉年华活动的组织者小安一共收到了 n个活动的举办申请,其中第 i 个
活动的起始时间为 Si,活动的持续时间为Ti。这些活动都可以安排到任意一个嘉
年华的会场,也可以不安排。
小安通过广泛的调查发现,如果某个时刻,两个嘉年华会场同时有活动在进
行(不包括活动的开始瞬间和结束瞬间),那么有的选手就会纠结于到底去哪个
会场,从而变得不开心。所以,为了避免这样不开心的事情发生,小安要求不能
有两个活动在两个会场同时进行(同一会场内的活动可以任意进行)。
另外,可以想象,如果某一个嘉年华会场的活动太少,那么这个嘉年华的吸
引力就会不足,容易导致场面冷清。所以小安希望通过合理的安排,使得活动相
对较少的嘉年华的活动数量最大。
此外,有一些活动非常有意义,小安希望能举办,他希望知道,如果第i 个
活动必须举办(可以安排在两场嘉年华中的任何一个),活动相对较少的嘉年华
的活动数量的最大值。
http://blog.sina.com.cn/s/blog_86942b140101557q.html
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 #include<map> 6 #include<algorithm> 7 using namespace std; 8 #define MAXN 210 9 pair<int,int> event[MAXN]; 10 int num[MAXN*2][MAXN*2],pre[2*MAXN][MAXN],back[2*MAXN][MAXN],ans[2*MAXN][2*MAXN]; 11 int a[MAXN*2]; 12 map<int,int> home; 13 int n,m; 14 void discretization() 15 { 16 sort(a+1,a+2*n+1); 17 int i,j=0; 18 a[0]=-1; 19 for(i=1;i<=2*n;i++) 20 { 21 if(a[i]!=a[i-1]) 22 j++; 23 home[a[i]]=j; 24 } 25 for(i=1;i<=n;i++) 26 { 27 event[i].first=home[event[i].first]; 28 event[i].second=home[event[i].second]; 29 //cout<<event[i].first<<" "<<event[i].second<<endl; 30 } 31 m=j; 32 } 33 void solve_all() 34 { 35 int i,j,k; 36 memset(num,0,sizeof(num)); 37 memset(pre,0xaf,sizeof(pre)); 38 memset(back,0xaf,sizeof(back)); 39 //cout<<pre[0][0]<<endl; 40 int ans=0; 41 pre[0][0]=0; 42 for(k=1;k<=n;k++) 43 for(i=0;i<=event[k].first;i++) 44 for(j=event[k].second;j<=m+1;j++) 45 num[i][j]++; 46 47 for(i=1;i<=m;i++) 48 for(j=0;j<=n;j++) 49 { 50 for(k=0;k<i;k++) 51 { 52 pre[i][j]=max(pre[i][j],pre[k][j]+num[k][i]); 53 if(j>=num[k][i]) 54 pre[i][j]=max(pre[i][j],pre[k][j-num[k][i]]); 55 } 56 //cout<<i<<" "<<j<<" "<<pre[i][j]<<endl; 57 } 58 back[m+1][0]=0; 59 for(i=m;i>=1;i--) 60 for(j=0;j<=n;j++) 61 { 62 for(k=i+1;k<=m+1;k++) 63 { 64 back[i][j]=max(back[i][j],back[k][j]+num[i][k]); 65 if(j>=num[i][k]) 66 back[i][j]=max(back[i][j],back[k][j-num[i][k]]); 67 } 68 //cout<<i<<" "<<j<<" "<<back[i][j]<<endl; 69 } 70 for(j=0;j<=n;j++) 71 ans=max(ans,min(j,pre[m][j])); 72 printf("%d\n",ans); 73 } 74 int calc(int i,int j,int x,int y) 75 { 76 return min(x+y+num[i][j],pre[i][x]+back[j][y]); 77 } 78 void solve_part() 79 { 80 int i,j,x,y,k; 81 memset(ans,0,sizeof(ans)); 82 int s=0; 83 for(i=1;i<=m;i++) 84 for(j=i;j<=m;j++) 85 { 86 y=n; 87 s=0; 88 for(x=0;x<=n;x++) 89 { 90 for(y;y>0;y--) 91 { 92 if(calc(i,j,x,y-1)<calc(i,j,x,y)) 93 break; 94 } 95 s=max(s,calc(i,j,x,y)); 96 } 97 ans[i][j]=s; 98 } 99 for(k=1;k<=n;k++) 100 { 101 s=0; 102 for(i=1;i<=event[k].first;i++) 103 for(j=event[k].second;j<=m;j++) 104 s=max(s,ans[i][j]); 105 printf("%d\n",s); 106 } 107 } 108 109 110 int main() 111 { 112 scanf("%d",&n); 113 int i; 114 for(i=1;i<=n;i++) 115 { 116 scanf("%d%d",&event[i].first,&event[i].second); 117 event[i].second+=event[i].first; 118 a[2*i-1]=event[i].first; a[2*i]=event[i].second; 119 } 120 discretization(); 121 solve_all(); 122 solve_part(); 123 return 0; 124 }