To push from a small range to a large range, we push from the back to the front. The i and j in dp[i][j] represent the minimum number of clothes to wear from i to j, and the current dp[i][j] is required. If a[i]!=a[j],
Then dp[i][j]=dp[i+1][j]+1, then we divide the interval with k, i<=k<=j; if a[i]==a[k], then dp [i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]), which is actually the one belonging to k
Don't count it once, why not write it as dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k+1][j])? In fact, it can be written like this, but the interval where k is located is (i, j].
#include<stdio.h> #include<string.h> #define inf 0x3f3f3f int n,m,k,t; int dp[105][105],a[105]; int min(int a,int b) { if(a>b) return b; return a; } intmain () { scanf("%d",&t); int count=0; while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } memset(dp,0,sizeof(dp)); for(int i=n;i>=1;i--) { for(int j=i;j<=n;j++) { dp[i][j]=dp[i+1][j]+1; for(int k=i;k<=j;k++) { if(a[i]==a[k]) dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j]); } } } printf("Case %d: %d\n",++count,dp[1][n]); } return 0; }
Change the formula:
#include<stdio.h> #include<string.h> #define inf 0x3f3f3f int n,m,k,t; int dp[105][105],a[105]; int min(int a,int b) { if(a>b) return b; return a; } intmain () { scanf("%d",&t); int count=0; while(t--) { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&a[i]); } memset(dp,0,sizeof(dp)); for(int i=n;i>=1;i--) { for(int j=i;j<=n;j++) { dp[i][j]=dp[i+1][j]+1; for(int k=i+1;k<=j;k++) { if(a[i]==a[k]) dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]); } } } printf("Case %d: %d\n",++count,dp[1][n]); } return 0; }