lightoj1422_区间dp
题目链接:http://lightoj.com/volume_showproblem.php?problem=1422
题意:给你n天分别要穿的衣服,可以套着穿,但是一旦脱下来就不能再穿了,问这n天要准备几件衣服。
思路:dp[i][j]为第i天到第j天要穿的最少衣服,考虑第i天,如果后面的[i+1, j]天的衣服不要管,那么dp[i][j] = dp[i + 1][j] + 1。
然后在区间[i +1, j]里面找到和第i天衣服一样的日子,尝试直到那天都不把i脱掉,
那么就变成dp[i][j] = dp[i + 1][k - 1] + dp[k][j],你可能会发现第i天不见了,其实只要把+两边换一下就好说了,就是第k天的衣服一直穿着。
1 #include <algorithm> 2 #include <iostream> 3 #include <cstring> 4 #include <cstdlib> 5 #include <cstdio> 6 #include <vector> 7 #include <ctime> 8 #include <queue> 9 #include <list> 10 #include <set> 11 #include <map> 12 using namespace std; 13 #define INF 0x3f3f3f3f 14 typedef long long LL; 15 16 int a[110], dp[110][110]; 17 int dfs(int l, int r) 18 { 19 if(dp[l][r] >= 0) 20 return dp[l][r]; 21 if(l > r) 22 return 0; 23 if(l == r) 24 return 1; 25 int sum = INF; 26 for(int k = l+1; k <= r; k++) 27 { 28 if(a[l] == a[k]) 29 sum = min(sum, dfs(l+1, k-1) + dfs(k, r)); 30 else 31 sum = min(sum, dfs(l+1, k-1) + dfs(k, r) + 1); 32 } 33 dp[l][r] = sum; 34 return sum; 35 } 36 int main() 37 { 38 int t, n; 39 scanf("%d", &t); 40 for(int ca = 1; ca <= t; ca++) 41 { 42 scanf("%d", &n); 43 for(int i = 1; i <= n; i++) 44 { 45 scanf("%d", &a[i]); 46 } 47 memset(dp, -1, sizeof(dp)); 48 printf("Case %d: %d\n", ca, dfs(1, n)); 49 } 50 return 0; 51 }