bzoj2708: [Violet 1]木偶
神题。
开始写了一发匈牙利。
然后又写了一发区间DP。
%完发现就是直接DP。
cal就是枚举可以删的点数。用hzwer的话:
cal(x,y)计算x-y互相匹配最多可扔掉几个
枚举可以扔掉的数量k,判断剩下的能否相互匹配,不能返回k-1
以及被扔掉的能否相互匹配,能匹配返回k-1
#include<cstdio> #include<iostream> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; int a[110],f[110]; int cal(int l,int r) { for(int i=1;i<=r-l+1;i++) { for(int j=l;j<=r-i;j++) if(abs(a[j]-a[j+i])>1)return i-1; if(abs(a[l+i-1]-a[r-i+1])<=1)return i-1; } return r-l+1; } int main() { int n; while(scanf("%d",&n)!=EOF) { for(int i=1;i<=n;i++)scanf("%d",&a[i]); sort(a+1,a+n+1); memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) for(int j=0;j<i;j++) f[i]=max(f[i],f[j]+cal(j+1,i)); printf("%d\n",f[n]); } return 0; }
pain and happy in the cruel world.