zoukankan      html  css  js  c++  java
  • POJ1722 Substruct

    题目:Substruct

    网址:http://poj.org/problem?id=1722

    Description

    We are given a sequence of N positive integers a = [a1, a2, ..., aN] on which we can perform contraction operations.
    One contraction operation consists of replacing adjacent elements ai and ai+1 by their difference ai-ai+1. For a sequence of N integers, we can perform exactly N-1 different contraction operations, each of which results in a new (N-1) element sequence.

    Precisely, let con(a,i) denote the (N-1) element sequence obtained from [a1, a2, ..., aN] by replacing the elements ai and ai+1 by a single integer ai-ai+1 :

    con(a,i) = [a1, ..., ai-1, ai-ai+1, ai+2, ..., aN]
    Applying N-1 contractions to any given sequence of N integers obviously yields a single integer.
    For example, applying contractions 2, 3, 2 and 1 in that order to the sequence [12,10,4,3,5] yields 4, since :
    con([12,10,4,3,5],2) = [12,6,3,5]

    con([12,6,3,5] ,3) = [12,6,-2]

    con([12,6,-2] ,2) = [12,8]

    con([12,8] ,1) = [4]

    Given a sequence a1, a2, ..., aN and a target number T, the problem is to find a sequence of N-1 contractions that applied to the original sequence yields T.

    Input

    The first line of the input contains two integers separated by blank character : the integer N, 1 <= N <= 100, the number of integers in the original sequence, and the target integer T, -10000 <= T <= 10000.
    The following N lines contain the starting sequence : for each i, 1 <= i <= N, the (i+1)st line of the input file contains integer ai, 1 <= ai <= 100.

    Output

    Output should contain N-1 lines, describing a sequence of contractions that transforms the original sequence into a single element sequence containing only number T. The ith line of the output file should contain a single integer denoting the ith contraction to be applied.
    You can assume that at least one such sequence of contractions will exist for a given input.

    Sample Input
    5 4
    12
    10
    4
    3
    5
    
    Sample Output
    2
    3
    2
    1
    
    Source

    CEOI 1998

    这题命题风格有点像codeforces

    经过观察发现,在a1~an中,a1以及a2的正负号是一定的,相反,其他的是任意的。(换句话说,题目要求:a1 - a2 +/- a3 +/- … +/- an = t);

    定义状态:dp[i, j]代表考虑第i位左端正负号,使得ai ~ an的和为j的可行性。(换句话讲,通过改变第i至n个数左侧正负号使得总和为j)

    不难想出转移方程:dp[i, j] = dp[i + 1, j + a[i]] | dp[i + 1, j - a[i]],dp[i, j] = 其中,true指该状态可行,false为不可行。

    但是由于j可能是负的,所以我们可以将t加上一个比较大的常数,使状态便于表示。

    本题核心在于如何寻找完整的操作顺序。

    由于总共n - 1个操作,真正影响序列结果的是顺序。我们先通过上述的DP状态处理每个数左端的正负号。

    我们考虑:若第i个数前符号为负号,那么它先进行操作一定是合理的。(此中有真意,欲辨已忘言,还请列位感受感受)

    由此我们先把左端符号为正号的数进行操作,接着从左到右将其余的数操作。对于前者,我们需要记录一个变量tot,用以记录已经进行操作次数。

    代码如下:

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    #include<vector>
    #include<cmath>
    using namespace std;
    const int maxn = 100 + 10;
    const int SIZE = 40000 + 5;
    vector <int> sub;
    int n, t, a[maxn], tot = 0;
    bool dp[maxn][SIZE];
    void search_route(int cur, int sum)
    {
    	if(cur > n) return;
    	if(dp[cur + 1][sum + a[cur]])
    	{
    		sub.push_back(0);
    		search_route(cur + 1, sum + a[cur]);
    	}
    	else if(dp[cur + 1][sum - a[cur]])
    	{
    		sub.push_back(1);
    		search_route(cur + 1, sum - a[cur]);
    	}
    	return;
    }
    int main()
    {
    	scanf("%d %d", &n, &t);
    	t += 20000;
    	for(int i = 1; i <= n; ++ i) scanf("%d", &a[i]);
    	t -= a[1] - a[2];
    	memset(dp, false, sizeof(dp));
    	dp[n + 1][20000] = true;
    	for(int i = n; i >= 3; -- i)
    	{
    		for(int j = a[i]; j <= 40000 - a[i]; ++ j)
    		{
    			dp[i][j] = dp[i + 1][j - a[i]] | dp[i + 1][j + a[i]];
    		}
    	}
    	sub.clear();
    	
    	sub.push_back(1), sub.push_back(0);
    	search_route(3, t);
    	for(int i = 1; i < sub.size(); ++ i)
    	{
    		if(sub[i] == 1)
    		{
    			printf("%d
    ", i - tot);
    			++ tot;
    		}
    	}
    	for(int i = 1; i < sub.size(); ++ i)
    	{
    		if(sub[i] == 0)
    		{
    			printf("%d
    ", 1);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    Effective Java 第三版——26. 不要使用原始类型
    Effective Java 第三版——25. 将源文件限制为单个顶级类
    Effective Java 第三版——24. 优先考虑静态成员类
    Effective Java 第三版——23. 优先使用类层次而不是标签类
    Effective Java 第三版——22. 接口仅用来定义类型
    Effective Java 第三版——21. 为后代设计接口
    Effective Java 第三版——20. 接口优于抽象类
    Effective Java 第三版——19. 如果使用继承则设计,并文档说明,否则不该使用
    Effective Java 第三版——18. 组合优于继承
    Effective Java 第三版——17. 最小化可变性
  • 原文地址:https://www.cnblogs.com/zach20040914/p/13004691.html
Copyright © 2011-2022 走看看