zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    Cocos2d-x3.0网络通信学习(一)
    Coding 初级教程(一)——用GitHub的GUI客户端对Coding的项目进行管理
    glob模式
    Cocos2d-x.3.0开发环境搭建
    Cocos2d-x.3.0开发环境搭建之—— 极简式环境搭建
    绘制图形与3D增强技巧(五)----多边形图元的使用及其他
    绘制图形与3D增强技巧(四)----多边形图元及其点画模式
    绘制图形与3D增强技巧(三)----三角形图元TRANGLE
    绘制图形与3D增强技巧(二)----直线图元之点画
    绘制图形与3D增强技巧(二)----直线图元
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4015613.html
Copyright © 2011-2022 走看看