BZOJ 1032 JSOI2007 祖码Zuma 动态规划
题目大意:给定一个祖玛序列,任选颜色射♂出珠子,问最少射♂出多少珠子
输入法近期越来越奇怪了0.0
首先我们把连续同样的珠子都缩在一起 令f[i][j]表示从i開始的j个珠子的最小消除次数
初值 f[i][1]=cnt[i]==1?2:1
然后对于每一个区间。我们枚举中间点,拆成两半求和
假设这个区间两端点颜色同样。我们还能够把中间消掉,然后两边再补射1或0个
尼玛珠子的颜色能够是0……由于这个WA了半天 真~!@#$%^&*()
此外此题是有BUG的 我的代码不能考虑将三个离散的珠子 聚在一起的情况 可是AC了
例:
7
1 2 2 1 3 3 1
ans:2
因此我又写了第二个版本号,在区间两側的珠子都是单个的时候去区间内部寻找第三个单个的珠子,结果数据原因WA掉了。可是确实能够过这组数据
希望官方能够把数据更新一下~(@^_^@)~
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 510 using namespace std; int n; pair<int,int>a[M]; int f[M][M]; int main() { int i,j,k,x; cin>>n; a[0].first=19980402; for(i=1,j=0;i<=n;i++) { scanf("%d",&x); if(x!=a[j].first) a[++j].first=x; a[j].second++; } n=j; memset(f,0x3f,sizeof f); for(i=1;i<=n;i++) f[i][1]=a[i].second==1?2:1; for(j=2;j<=n;j++) for(i=1;i+j-1<=n;i++) { if(a[i].first==a[i+j-1].first) f[i][j]=f[i+1][j-2]+(a[i].second+a[i+j-1].second==2?1:0); for(k=1;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[i+k][j-k]); } cout<<f[1][n]<<endl; }
能过那组数据可是WA掉的代码
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 510 using namespace std; int n; pair<int,int>a[M]; int f[M][M]; int main() { int i,j,k,x; cin>>n; a[0].first=19980402; for(i=1,j=0;i<=n;i++) { scanf("%d",&x); if(x!=a[j].first) a[++j].first=x; a[j].second++; } n=j; memset(f,0x3f,sizeof f); for(i=1;i<=n;i++) f[i][1]=a[i].second==1?2:1; for(j=2;j<=n;j++) for(i=1;i+j-1<=n;i++) { if(a[i].first==a[i+j-1].first) { if(a[i].second+a[i+j-1].second==2) { f[i][j]=f[i+1][j-2]+1; for(k=2;k<j;k++) if(a[i+k-1].first==a[i].first&&a[i+k-1].second==1) f[i][j]=min(f[i][j],f[i+1][k-2]+f[i+k][j-k-1]); } else f[i][j]=f[i+1][j-2]; } for(k=1;k<j;k++) f[i][j]=min(f[i][j],f[i][k]+f[i+k][j-k]); } cout<<f[1][n]<<endl; }