zoukankan      html  css  js  c++  java
  • UVa 1025

    开始系统跟着刘汝佳老师的书并行刷题。

    DP问题似乎很多问题是会将时间这类有序的量作为状态一个坐标,这个思路还是蛮惊奇的,建立在题目中时间是整数,并且数量级可以接受的情况。

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <queue>
    #include <cmath>
    using namespace std;
    
    const int maxn= 55;
    const int maxt= 205;
    const int INF= 0x3f3f3f3f;
    int tt[maxn], ls[maxn], rs[maxn];
    int has_train[maxt][maxn][2];
    int dp[maxt][maxn];
    
    void Init(int t, int n)
    {
    	memset(dp, 0x3f, sizeof(dp));
    	memset(tt, 0, sizeof(tt));
    	memset(ls, 0, sizeof(ls));
    	memset(rs, 0, sizeof(rs));
    	memset(has_train, 0, sizeof(has_train));
    	dp[t][n]= 0;
    }
    void SetHasTrain(int t, int n, int m1, int m2)
    {
    	int b= 0;
    	for (int i= 1; i<= n-1; ++i){
    		b+= tt[i-1];
    		for (int d= 0; d< m1; ++d){
    			if (b+ls[d]<= t){
    				has_train[b+ls[d]][i][0]= 1;
    			}
    		}
    	}
    	b= 0;
    	for (int i= n; i> 1; --i){
    		b+= tt[i];
    		for (int d= 0; d< m2; ++d){
    			if (b+rs[d]<= t){
    				has_train[b+rs[d]][i][1]= 1;
    			}
    
    		}
    	}
    }
    
    int main(int argc, char const *argv[])
    {
    	int n, t, m1, m2;
    	int kase= 0;
    
    	while (1){
    		scanf("%d", &n);
    		if (0== n){
    			break;
    		}
    		scanf("%d", &t);
    		Init(t, n);
    
    		for (int i= 1; i< n; ++i){
    			scanf("%d", tt+i);
    		}
    
    		scanf("%d", &m1);
    		for (int i= 0; i< m1; ++i){
    			scanf("%d", ls+i);
    		}
    		scanf("%d", &m2);
    		for (int i= 0; i< m2; ++i){
    			scanf("%d", rs+i);
    		}
    		SetHasTrain(t, n, m1, m2);
    
    		for (int i= t-1; i>= 0; --i){
    			for (int j= n; j> 0; --j){
    				int x= dp[i+1][j]+1;
    				//left
    				if (j> 1 && has_train[i][j][1] && i+tt[j-1]<= t){
    					x= min(x, dp[i+tt[j-1]][j-1]);
    				}
    				// right
    				if (j< n && has_train[i][j][0] && i+tt[j]<= t){
    					x= min(x, dp[i+tt[j]][j+1]);
    				}
    
    				dp[i][j]= x;
    			}
    		}
    
    		cout<<"Case Number "<<++kase<<": ";
    		if (dp[0][1]>= INF){
    			cout<<"impossible"<<endl;
    		}
    		else{
    			cout<<dp[0][1]<<endl;
    		}
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    [cf1038E][欧拉路]
    [最小费用最大流(板子)]
    [网络流24题]
    [ACM International Collegiate Programming Contest, Amman Collegiate Programming Contest (2018)]
    [Split The Tree][dfs序+树状数组求区间数的种数]
    [CSL 的魔法][求排序最少交换次数]
    [CSL 的字符串][栈,模拟]
    ZOJ 3949 Edge to the Root 树形DP
    第十三周 Leetcode 363. Max Sum of Rectangle No Larger Than K(HARD)
    POJ 2104 HDU 2665 主席树 解决区间第K大
  • 原文地址:https://www.cnblogs.com/Idi0t-N3/p/13721983.html
Copyright © 2011-2022 走看看