标签:
题目链接:http://acm.swust.edu.cn/problem/0581/
10 3
2 1 2 2 1 1 3 1 3 3
0 0
|
2 |
for (L = 0; L < k; L++){ if (L != x && dp[j | (1 << x)][x] < dp[j][L] + 1) //不含x类的段加一生成的新段如果大于相同状态的值,更新 dp[j | (1 << x)][x] = dp[j][L] + 1; }
(5)最后查询所有dp[1<<k-1][i]状态下的最长可行序列,用总长度减去即可
dp方程总结如下
每输入一个x
if(s&(1<<x) dp[s][x] = dp[s][x] + 1 else dp[1<<x|s][x] = max(dp[1<<x|s][x],dp[s][L]+1) L(0,k)
代码如下:
1 #include <iostream> 2 #include <cstring> 3 using namespace std; 4 int main(){ 5 int m, k, dp[1 << 5][5]; 6 //dp[][k] 二进制每一位对应含有第k类石子,表示以第k类石子结尾含有1<<5每一位对应下石子的最大值 7 while (cin >> m >> k, m || k){ 8 int i, x, j, L, t = 1 << k, maxn = 0; 9 memset(dp, 0, sizeof(dp)); 10 for (i = 0; i < m; i++){ 11 cin >> x; 12 x--; 13 for (j = 0; j < t; j++){ 14 if (j&(1 << x)) //对于前面也是以x类石子结尾的最大值直接加1 15 dp[j][x]++; 16 } 17 for (j = 0; j < t; j++){ 18 if (!(j&(1 << x))) //前面不含x类石子 19 for (L = 0; L < k; L++){ 20 if (L != x && dp[j | (1 << x)][x] < dp[j][L] + 1) //不含x类的段加一生成的新段如果大于相同状态的值,更新 21 dp[j | (1 << x)][x] = dp[j][L] + 1; 22 } 23 } 24 } 25 for (i = 0; i<k; i++) 26 if (dp[(1 << k) - 1][i]>maxn) 27 maxn = dp[(1 << k) - 1][i]; 28 cout << m - maxn << endl; 29 } 30 return 0; 31 }
标签:
原文地址:http://www.cnblogs.com/zyxStar/p/4605954.html