codeforces 607B- Zuma(区间DP)
传送门:QAQQAQ
题意:给你一个数组,每次可以删一个连续的回文串(包括长度为1),问最少删几次
思路:挺简单的DP题,但要想清楚有难度(先看数据范围,n^3可以过)
区间DP,dp[i][j]可以有两种情况更新而来:
1.a[i]==a[j],把最外面一层挖掉,答案为dp[i+1][j-1]
2.对于所有dp[i][j],枚举中间点,把它切成两半,分别求回文串加起来
为减少更新时溢出等不必要的麻烦,我把len=1或2都特判掉了
代码:
#include<bits/stdc++.h> using namespace std; const int inf=(int)2e9; int dp[505][505]; int n,a[505]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); for(int i=1;i<=n;i++) { for(int j=i;j<=n;j++) { if(i==j) dp[i][j]=1; else dp[i][j]=inf; } } for(int i=1;i<n;i++) { if(a[i]==a[i+1]) dp[i][i+1]=1; else dp[i][i+1]=2; } for(int len=3;len<=n;len++) { for(int i=1;i<=n-len+1;i++) { int j=i+len-1; if(a[i]==a[j]) dp[i][j]=dp[i+1][j-1]; for(int k=i;k<j;k++) { dp[i][j]=min(dp[i][k]+dp[k+1][j],dp[i][j]); } } } cout<<dp[1][n]<<endl; }