题目
题意:
切水果,告诉你每个水果出现时间和消失时间,没有炸弹。任何时候你都可以切水果,一切就会把全部都切掉,当超过3个或三个水果被切时,就是连击,连击分等于水果个数。问最大的连击分数。
解法:
按出现时间排序,然后问题转为在某些水果出现后切掉全部在场水果的DP问题。
可以用一个按消失时间排序的优先队列。
一开始理解错题意,以为可以不切完,所以错了三次。
Time:595ms Memory:0KB Length:1874B #include<iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <set> #include <map> #include <algorithm> #define MAXN 1010 #define MP(x,y) make_pair((x),(y)) #define FI first #define SE second using namespace std; int n; map<int, int> ma; int dp[MAXN<<1], ind[MAXN<<1]; struct node { int s, e; }p[MAXN]; bool cmp(node a,node b) { if (a.s==b.s) return a.e<b.e; return a.s<b.s; } int a[MAXN<<1][MAXN]; int main() { //freopen("/home/moor/input.txt","r",stdin); int cas, t=0; scanf("%d", &cas); while (cas--) { scanf("%d", &n); ma.clear(); memset(dp, 0, sizeof(dp)); memset(a, 0, sizeof(a)); int m=0; for (int i=0; i<n; i++) { scanf("%d %d", &p[i].s, &p[i].e); ind[m++]=p[i].s; ind[m++]=p[i].e; } sort(p, p+n, cmp); sort(ind, ind+m); int tmp, cnt=1; ma[ind[0]]=1; for (int i=1; i<2*n; i++) if (ind[i]!=ind[i-1]) ma[ind[i]]=(++cnt); for (int i=0; i<n; i++) { p[i].s=ma[p[i].s]; p[i].e=ma[p[i].e]; } for (int i=1; i<=cnt; i++) for (int j=0; j<n; j++) if (p[j].s<=i&&p[j].e>=i) { a[i][0]++; a[i][a[i][0]]=j; } int ans=0; for (int i=1; i<=cnt; i++) { int add=0, tmp=a[i][0]; for (int j=i-1; j>=p[a[i][1]].s-1; j--) { while (tmp>0 && p[a[i][tmp]].s>j) tmp--, add++; if (add>2) dp[i]=max(dp[i], dp[j]+add); else dp[i]=max(dp[i], dp[j]); } ans=max(ans, dp[i]); } printf("Case #%d: %d\n", ++t, ans); } return 0; }