zoukankan      html  css  js  c++  java
  • POJ2430 Lazy Cows

    vjudge传送


    这题与其说是状压dp,到更像是插头dp。


    看到(B)那么大,肯定要先离散化,然后再预处理出来每一列牛的位置,即有一头还是两头,在上面还是下面。


    转移其实比较显然,就是有点恶心。
    (dp[i][j])中的(j)分四种情况:
    1.棚子只建在第一行。
    2.棚子只建在第二行。
    3.两个棚子分别建在两行。
    4.一个棚子覆盖了两行。


    那么我们需要根据这一列牛的位置考虑每一个状态怎么转移。比如如果只有上面有一头牛,那么(dp[i][1])可以直接新建一个棚子,也可以从(dp[i-1][1],dp[i-1][3])延伸过来。需要注意的是,延伸要算上和上一列的牛之间的距离,而新建增加的面积是1.
    其他情况与此类似,详见代码吧。


    debug挺久的。

    #include<cstdio>
    #include<iostream>
    #include<cmath>
    #include<algorithm>
    #include<cstring>
    #include<cstdlib>
    #include<cctype>
    #include<vector>
    #include<queue>
    #include<assert.h>
    #include<ctime>
    using namespace std;
    #define enter puts("") 
    #define space putchar(' ')
    #define Mem(a, x) memset(a, x, sizeof(a))
    #define In inline
    #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt)
    typedef long long ll;
    typedef double db;
    const ll INF = 1e14;
    const db eps = 1e-8;
    const int maxn = 1e3 + 5;
    In ll read()
    {
    	ll ans = 0;
    	char ch = getchar(), las = ' ';
    	while(!isdigit(ch)) las = ch, ch = getchar();
    	while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar();
    	if(las == '-') ans = -ans;
    	return ans;
    }
    In void write(ll x)
    {
    	if(x < 0) x = -x, putchar('-');
    	if(x >= 10) write(x / 10);
    	putchar(x % 10 + '0');
    }
    In void MYFILE()
    {
    #ifndef mrclr
    	freopen("random.in", "r", stdin);
    	freopen("ha.out", "w", stdout);
    #endif
    }
    
    int n, m, B;
    int l[maxn], pos[maxn];
    int li[maxn], _n, buc[maxn], num[maxn];		//buc: 0:up 1:down 2:both
    
    ll dp[maxn][maxn][5];
    
    int main()
    {
    //	MYFILE();
    	while(scanf("%d%d%d", &n, &m, &B) != EOF)
    	{
    		Mem(buc, 0);
    		for(int i = 1; i <= n; ++i)
    		{
    			l[i] = read(), pos[i] = read();
    			li[i] = pos[i];
    		}
    		sort(li + 1, li + n + 1);
    		_n = unique(li + 1, li + n + 1) - li - 1;
    		for(int i = 1; i <= n; ++i)
    		{
    			int p = lower_bound(li + 1, li + _n + 1, pos[i]) - li;
    			if(l[i] == 2) buc[p] = 1;
    			if(++num[p] > 1) buc[p] = 2;
    		}
    		Mem(dp, 0x3f);
    		dp[0][0][3] = 0;
    		li[0] = li[1] - 1;
    		for(int i = 1; i <= _n; ++i)
    		{
    			int dis = li[i] - li[i - 1];
    			for(int j = 1; j <= m; ++j)
    			{
    				ll Min1 = INF, Min2 = INF;
    				for(int k = 1; k <= 4; ++k)
    				{
    					Min1 = min(Min1, dp[i - 1][j - 1][k]);
    					Min2 = min(Min2, j - 2 >= 0 ? dp[i - 1][j - 2][k] : INF);	
    				} 
    				if(buc[i] == 0 || buc[i] == 1)
    				{
    					int k = buc[i] + 1;
    					dp[i][j][k] = min(dp[i][j][k], min(dp[i - 1][j][k], dp[i - 1][j][3]) + dis);
    					dp[i][j][k] = min(dp[i][j][k], Min1 + 1);	
    				}
    				dp[i][j][3] = min(dp[i][j][3], min(dp[i - 1][j - 1][1], dp[i - 1][j - 1][2]) + dis + 1);
    				dp[i][j][3] = min(dp[i][j][3], min(dp[i - 1][j][3] + (dis << 1), Min2 + 2));
    				dp[i][j][4] = min(dp[i][j][4], min(Min1 + 2, dp[i - 1][j][4] + (dis << 1)));
    			}
    		}
    		ll ans = INF;
    		for(int j = 1; j <= 4; ++j) 
    			ans = min(ans, dp[_n][m][j]);
    		write(ans), enter;
    	}
    	return 0;
    }
    
  • 相关阅读:
    @RequestParam注解使用:Name for argument type [java.lang.String] not available, and parameter name information not found in class file either.
    cglib动态代理导致注解丢失问题及如何修改注解允许被继承
    springboot Autowired BeanNotOfRequiredTypeException
    git根据用户过滤提交记录
    不同包下,相同数据结构的两个类进行转换
    How to use Jackson to deserialise an array of objects
    jooq实践
    java如何寻找main函数对应的类
    Python--matplotlib
    Python 和 Scikit-Learn
  • 原文地址:https://www.cnblogs.com/mrclr/p/13839439.html
Copyright © 2011-2022 走看看