HDU 3237 Help Bubu(DP)

题目链接:点击打开链接

思路:

比赛时查一点出, 需要加一个优化才能防止超时(恶心), 状态很容易想到: d[i][j][s][k]表示前i本书拿了j本没拿的书的集合是s没拿的书的最后一本是k的最优解。

为什么状态压缩的是目前桌子上的书的集合呢?  因为我们要防止一种情况:那就是如果对于高度为H的一种书, 我们都拿走了, 那么还要放回桌子上, 最优解要+1, 这样表示之后, 我们只要判断一下有几种书桌子上没有就行了。

细节参见代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>
#include <list>
#include <deque>
#include <map>
#include <queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
typedef long double ld;
const double eps = 1e-6;
const double PI = acos(-1);
const int mod = 1000000000 + 7;
const int INF = 0x3f3f3f3f;
// & 0x7FFFFFFF
const int seed = 131;
const ll INF64 = ll(1e18);
int T,n,K,a[111],d[2][111][(1<<8)][10], kase = 0;
int tot, state,one[1<<8];
inline void init(int u) {
        for(int j = 0; j <= K; j++) {
            for(int s = 0; s < (1<<(tot+1)); s++) {
                for(int k = 0; k <= tot+1; k++) {
                    d[u][j][s][k] = INF;
                }
            }
        }
}
void Initial() {
    for (int i = 0; i < (1<<8); ++i) {
        for (int j = 0; j < 8; ++j)
            if (i & (1<<j)) one[i]++;
    }
}
int main() {
    Initial();
    while(~scanf("%d%d", &n, &K)) {
        if(n == 0 && K == 0) break;
        tot = 0;
        state = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            a[i] -= 25;
            tot = max(tot, a[i]);
            state |= 1<<a[i];
        }
        int u = 0;
        init(u);
        d[u][0][0][tot+1] = 0;
        for(int i = 0; i < n; i++) {
            int id = a[i+1];
            u ^= 1;
            init(u);
            for(int j = 0; j <= K; j++) {
                for(int s = 0; s < (1<<(tot+1)); s++) {
                    for(int k = 0; k <= tot+1; k++) {
                            int& ans = d[u^1][j][s][k];
                            if(ans == INF) continue;

                            if(j < K) d[u][j+1][s][k] = min(d[u][j+1][s][k], ans);

                            if(k != id) d[u][j][s|(1<<id)][id] = min(d[u][j][s|(1<<id)][id], ans+1);
                            else d[u][j][s][id] = min(d[u][j][s][id], ans);
                    }
                }
            }
        }
        int ans = INF;
        for(int j = 0; j <= K; j++) {
            for(int s = 0; s < (1<<(tot+1)); s++) {
                for(int k = 0; k < tot+1; k++) {
                    int cur = 0;
                    if(d[u][j][s][k] == INF) continue;
                    int st = state ^ s;
                    ans = min(ans, d[u][j][s][k] + one[st]);
                }
            }
        }
        printf("Case %d: %d\n\n", ++kase, ans);
    }
    return 0;
}
时间: 2024-11-08 19:23:45

HDU 3237 Help Bubu(DP)的相关文章

HDU 4745 Two Rabbits(DP)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意:n个数排成一个环.两个人AB初始时各自选定一个位置.每一轮A在顺时针方向选择一个位置,B在逆时针选择一个位置,且这两个人所选位置的数字相等,然后格子跳到新选的位置上.问最多进行多少轮?有一个限制为每次跳跃不能跨过以前自己曾经选过的格子. 思路:主要是分析问题的本质.其实就是求最长回文子列.f[i][j]为[i,j]的最长回文子列,则答案为max(f[1][i],f[i+1][n]). i

HDU 4833 Best Financing (DP)

Best Financing Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 29    Accepted Submission(s): 3 Problem Description 小A想通过合理投资银行理财产品达到收益最大化.已知小A在未来一段时间中的收入情况,描述为两个长度为n的整数数组dates和earnings,表示在第dat

HDU 1260:Tickets(DP)

Tickets Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 923    Accepted Submission(s): 467 Problem Description Jesus, what a great movie! Thousands of people are rushing to the cinema. However,

hdu 1421 搬寝室 (dp)

思路分析: dp[i][j] 表示选取到第 i 个   组成了 j 对的最优答案. 当然排序之后 选取相邻两个是更优的. if(i==j*2) dp[i][j] = dp[i-2][j-1] + w[i]-w[i-2]^2.. else if( i> j*2 ) dp[i][j] = min (dp[i-2][j-1] + ...^2   ,    dp[i-1][j]).... #include <cstdio> #include <iostream> #include &

HDU 1159——Common Subsequence(DP)

Common Subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 23279    Accepted Submission(s): 10242 Problem Description A subsequence of a given sequence is the given sequence with some e

HDU 5791:Two(DP)

http://acm.hdu.edu.cn/showproblem.php?pid=5791 Two Problem Description Alice gets two sequences A and B. A easy problem comes. How many pair of sequence A' and sequence B' are same. For example, {1,2} and {1,2} are same. {1,2,4} and {1,4,2} are not s

hdu 1176 免费馅饼(DP)

题意: 都说天上不会掉馅饼,但有一天gameboy正走在回家的小径上,忽然天上掉下大把大把的馅饼.说来gameboy的人品实在是太好了,这馅饼别处都不掉,就掉落在他身旁的10米范围内.馅饼如果掉在了地上当然就不能吃了,所以gameboy马上卸下身上的背包去接.但由于小径两侧都不能站人,所以他只能在小径上接.由于gameboy平时老呆在房间里玩游戏,虽然在游戏中是个身手敏捷的高手,但在现实中运动神经特别迟钝,每秒种只有在移动不超过一米的范围内接住坠落的馅饼. 为了使问题简化,假设在接下来的一段时间

hdu 2189 来生一起走(DP)

题意: 有N个志愿者.指挥部需要将他们分成若干组,但要求每个组的人数必须为素数.问不同的方案总共有多少.(N个志愿者无差别,即每个组的惟一标识是:人数) 思路: 假设N个人可分为K组,将这K组的人数从小到大排序,num1,...,numk. 故N个人分组的方案数dp[n]=sum(dp[numk]) (所有分为K组的不同方案的和) 代码: bool yes[155]; int prime[155]; int dp[155]; int main(){ mem(yes,true); int C =

hdu 4055 Number String(dp)

Problem Description The signature of a permutation is a string that is computed as follows: for each pair of consecutive elements of the permutation, write down the letter 'I' (increasing) if the second element is greater than the first one, otherwis