• UVA 11578


    题目链接:11578 - Situp Benches

    题意:健♂身♂房有两个仰卧起坐坐垫,每次调整角度要花费10元/10度,每次使用要花费15,如今给定n个人的时间顺序,和所希望的角度,求最少花费
    思路:dp,dp[i][j][k]表示第i个人,一个角度为j,还有一个为k的最小花费,一个人用和两个人用的情况分开讨论,然后记录dp状态转移路径。这个输出路径让这题变得麻烦了不少。只是机智的我还是把它搞♂出♂来♂了。
    代码:
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <algorithm>
    using namespace std;
    #define INF 0x3f3f3f3f
    #define min(a,b) ((a)<(b)?(a):(b))
    const int N = 10005;
    int t, n, i, j, k, dp[N][5][5], ans, an[N];
    struct Stu {
    	int t, l, id;
    } s[N];
    
    struct Out {
    	int n, l, r, out1, out2;
    } out[N][5][5];
    
    bool cmpt(Stu a, Stu b) {
    	return a.t < b.t;
    }
    
    bool cmpid(Stu a, Stu b) {
    	return a.id < b.id;
    }
    
    void print(int n, int l, int r) {
    	Out next = out[n][l][r];
    	if (n == 0) return;
    	if (next.out2 != -1) {
    		an[s[n - 1].id] = next.out1;
    		an[s[n].id] = next.out2;
    	}
    	else {
    		an[s[n].id] = next.out1;
    	}
    	print(next.n, next.l, next.r);
    }
    
    int main() {
    	scanf("%d", &t);
    	while (t--) {
    		ans = INF;
    		memset(dp, INF, sizeof(dp));
    		dp[0][0][0] = 0;
    		scanf("%d", &n);
    		for (i = 1; i <= n; i++) {
    			scanf("%d%d", &s[i].t, &s[i].l);
    			s[i].l = s[i].l / 10 - 1;
    			s[i].id = i;
    		}
    		sort(s + 1, s + n + 1, cmpt);
    		for (i = 1; i <= n; i++) {
    			int tmp1 = s[i].l;
    			if (i == n || s[i].t != s[i + 1].t) {
    				for (j = 0; j < 5; j++) {
    					for (k = 0; k < 5; k++) {
    						if (dp[i][tmp1][k] > dp[i - 1][j][k] + abs(tmp1 - j) * 10) {
    							dp[i][tmp1][k] = dp[i - 1][j][k] + abs(tmp1 - j) * 10;
    							out[i][tmp1][k].l = j; out[i][tmp1][k].r = k; out[i][tmp1][k].n = i - 1;
    							out[i][tmp1][k].out1 = 1; out[i][tmp1][k].out2 = -1;
    						}
    						if (dp[i][j][tmp1] > dp[i - 1][j][k] + abs(tmp1 - k) * 10) {
    							dp[i][j][tmp1] = dp[i - 1][j][k] + abs(tmp1 - k) * 10;
    							out[i][j][tmp1].l = j; out[i][j][tmp1].r = k; out[i][j][tmp1].n = i - 1;
    							out[i][j][tmp1].out1 = 2; out[i][j][tmp1].out2 = -1;
    						}
    					}
    				}
    			}
    			else {
    				int tmp2 = s[i + 1].l;
    				for (j = 0; j < 5; j++) {
    					for (k = 0; k < 5; k++) {
    						if (dp[i + 1][tmp1][tmp2] > dp[i - 1][j][k] + abs(tmp1 - j) * 10 + abs(tmp2 - k) * 10) {
    							dp[i + 1][tmp1][tmp2] = dp[i - 1][j][k] + abs(tmp1 - j) * 10 + abs(tmp2 - k) * 10;
    							out[i + 1][tmp1][tmp2].l = j; out[i + 1][tmp1][tmp2].r = k; out[i + 1][tmp1][tmp2].n = i - 1;
    							out[i + 1][tmp1][tmp2].out1 = 1; out[i + 1][tmp1][tmp2].out2 = 2;
    						}
    						if (dp[i + 1][tmp2][tmp1] > dp[i - 1][j][k] + abs(tmp2 - j) * 10 + abs(tmp1 - k) * 10) {
    							dp[i + 1][tmp2][tmp1] = dp[i - 1][j][k] + abs(tmp2 - j) * 10 + abs(tmp1 - k) * 10;
    							out[i + 1][tmp2][tmp1].l = j; out[i + 1][tmp2][tmp1].r = k; out[i + 1][tmp2][tmp1].n = i - 1;
    							out[i + 1][tmp2][tmp1].out1 = 2; out[i + 1][tmp2][tmp1].out2 = 1;
    						}
    					}
    				}
    				i++;
    			}
    		}
    		int lv, rv;
    		for (j = 0; j < 5; j++) {
    			for (k = 0; k < 5; k++) {
    				if (ans > dp[n][j][k] + j * 10 + k * 10) {
    					ans = dp[n][j][k] + j * 10 + k * 10;
    					lv = j; rv = k;
    				}
    			}
    		}
    		printf("%d
    ", ans + 15 * n);
    		print(n, lv, rv);
    		for (i = 1; i <= n; i++)
    			printf("%d
    ", an[i]);
    	}
    	return 0;
    }


  • 相关阅读:
    php使用iconv进行从utf8转为gb2312字符编码出错解决方案
    PHP 的 cURL库快速入门文档
    转载 DISCUZ!X1程序目录、文件列表及模板文件结构说明,帮助大家二级开发
    下拉菜单部分选项不允许选择
    Htaccess文件用法集锦
    MYSQL server has gone away解决办法
    Discuz X 模板中获取用户头像
    CSS Hack
    VS轻松保存重复多用的代码片段
    三菱FX PLC编程口通讯协议详解
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4015613.html
Copyright © 2020-2023  润新知