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;
    }
    
  • 相关阅读:
    AD9 如何画4层pcb板
    在Altium Designer 2009下如何添加Logo图
    [置顶] 整数拆分 整合算法
    altium designer 中的top/bottom solder和top/bottom paste mask
    vs2012 与 win7 不兼容的问题
    poj1742 Coins
    poj3181 Dollar Dayz
    poj1065 Wooden Sticks
    poj1631 Bridging signals
    poj3666 Making the Grade
  • 原文地址:https://www.cnblogs.com/zach20040914/p/13004691.html
Copyright © 2011-2022 走看看