zoukankan      html  css  js  c++  java
  • HDU 4689 Derangement【DP递推】【好题】【思维题】

    Derangement

    Time Limit: 7000/7000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)
    Total Submission(s): 1170    Accepted Submission(s): 396


    Problem Description
    A derangement is a permutation such that none of the elements appear in their original position. For example, [5, 4, 1, 2, 3] is a derangement of [1, 2, 3, 4, 5]. Subtracting the original permutation from the derangement, we get the derangement difference [4, 2, -2, -2, -2], where none of its elements is zero. Taking the signs of these differences, we get the derangement sign [+, +, -, -, -]. Now given a derangement sign, how many derangements are there satisfying the given derangement sign?
     

    Input
    There are multiple test cases. Process to the End of File.
    Each test case is a line of derangements sign whose length is between 1 and 20, inclusively.
     

    Output
    For each test case, output the number of derangements.
     

    Sample Input
    +- ++---
     

    Sample Output
    1 13
     

    Author
    Zejun Wu (watashi)
     

    Source

    题意:1到n的n个数,打乱后减去原来的数的正负号,形成一串正负号的字符串,如[1,2,3,4,5]打乱后变成[5,4,1,2,3]就是[+,+,-,-,-]。给定这样一串正负号形成的字符串,有几种排列方式。

    dp[i][j]表示前i个位置中有j个空位(+号)没有确定负号全部确定

    “+'时

    要么使空位增加,要么不变

    增加时,直接空位增加:dp[i][i]+=dp[i-1][j-1]

    不变时,表示把当前的数填到前面未确定的j个空位中去:dp[i][j]+=dp[i-1][j]*j

    ‘-'时,因为必须确定

    要么减少,要么不变

    不变时,表示把当前数填到前面的j个空位中:dp[i][j]+=dp[i-1][j]*j

    减少时,表示把当前数填到前j-1位中去,再从前j-1位中拿一个数填到当前位:dp[i][j]+=dp[i-1][j-1]*(j-1)*(j-1)


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    #define ll long long
    
    ll dp[30][30];
    char num[100];
    
    int main()
    {
    	while (~scanf("%s", num))
    	{
    		int len = strlen(num);
    		memset(dp, 0, sizeof(dp));
    		dp[0][0] = 1;
    		for (int i = 1; i <= len; i++)
    		{
    			if (num[i - 1] == '+')
    			{
    				for (int j = 0; j <= i; j++)
    				{
    					dp[i][j] += dp[i - 1][j - 1];
    					dp[i][j] += dp[i - 1][j] * (ll)j;
    				}
    			}
    			else
    			{
    				for (int j = 0; j <= i; j++)
    				{
    					// dp[i][j - 1] += dp[i - 1][j] * j * j;
    					dp[i][j] += dp[i - 1][j] * (ll)j;
    					dp[i][j] += dp[i - 1][j + 1] * (ll)(j + 1) * (ll)(j + 1);
    				}
    			}
    		}
    		// printf("%lld
    ", dp[len][0]);
    		cout << dp[len][0] << endl;
    	}
    	return 0;
    }




    Fighting~
  • 相关阅读:
    linux相关的常用站点
    基于命令行的网络调试和测试工具
    清除DNS缓存
    数组映射
    react-native 自定义多选
    weex 长按图片保存
    MySql常用总结
    git常用命令
    react-native 自制多选功能
    react-native setState无法保持更新
  • 原文地址:https://www.cnblogs.com/Archger/p/12774753.html
Copyright © 2011-2022 走看看