SRM 308 Wardrobe

来源:互联网 发布:ami桌面知乎 编辑:程序博客网 时间:2024/06/05 14:44

题目大意  给出螺丝钉和匹配的螺丝帽每个大小为pi

实际中螺丝钉可以与正负1的螺丝帽匹配。每次取出一个螺丝钉找一个匹配的螺丝帽匹配,问最后最多能剩下多少个不匹配的螺丝钉。


首先排序,然后DP,f[i]=max(f[j], calc(j+1,i))

calc(j+1,i)表示这段直接匹配最多多少个剩余,贪心。枚举扔掉最小的k个螺丝钉和k个最大的螺丝帽看是否情况成立。


两端相邻区间如果存在相互影响的部

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;const int MAXN = 105;int cost[MAXN][MAXN];int f[MAXN],p[MAXN];int n;int   match(int L,int R){      if (abs(p[L]-p[R])<=1) return 0;      int ans = 0;      for (int k = 1;k<=R-L-1;++k)      {          bool can = true;          for (int i = L;i+k<=R;++i)              if (abs(p[i]-p[i+k])>1) can = false;          if ((abs(p[L+k-1]-p[R-k+1]) > 1) && can) ans =  k;       }      return ans;}int main(){        while (~scanf("%d",&n))    {          for (int i = 1 ; i <=n;++i) scanf("%d", &p[i]);          sort(p+1,p+n+1);          for (int i = 0 ; i <=n;++i) f[i] = 0;          for (int i = 1 ; i <=n;++i)              for (int j = i;j <=n;++j) cost[i][j] = match(i,j);                        for (int i = 1; i <=n;++i)              for (int j = 0;j<i;++j) f[i]=max(f[i],f[j]+cost[j+1][i]);          cout << f[n] << endl;    }    return 0;}

分,则可以通过调整改变。