[점프형 dp] A015LC_DI 서열의 유효한 배열 (앞의 숫자에 따라 뒤의 숫자)

7971 단어 #점진형dp

1. Problem


우리는 S, {'D', 'I'}에서 유래한 길이가 n인 문자열을 보여 줍니다.(이 문자들은'감소'와'증가'를 대표한다.)
유효한 배열은 정수 {0,1,...,n}에 대한 배열 P[0],P[1],...,P[n]로 모든 i에 대해
  • 만약에 S[i]='D'가 있다면 P[i]>P[i+1], 그리고;
  • 만약에 S[i]='I'가 있다면 P[i]몇 개의 유효한 배열이 있습니까?답이 많을 수 있으니 답안 모드 10^9+7
      :"DID"
      :5
      :
    (0, 1, 2, 3)         :
    (1, 0, 3, 2)
    (2, 0, 3, 1)
    (2, 1, 3, 0)
    (3, 0, 2, 1)
    (3, 1, 2, 0)
    

    팁:
    1 <= S.length <= 200 S는 컬렉션 {"D", "I"}의 문자로만 구성됩니다.

    2. 솔루션


    방법1:dp


    사색
    이 문제는 승강과 관련이 있으니 적어도 두 차원은 있어야 한다.
    그리고 한 서열에서 {0,..., i-2, i-1,i}, 뒷수 i는 틀림없이 앞의 수 i-1을 바탕으로 얻어진 것이고 뒷수의 선택은 여러 가지가 있을 수 있기 때문에 합법적인 숫자를 매거해야 한다.
    마지막으로 끊임없이bottom-up이 교체되어 최종 결과를 얻었습니다.
    사고의 방향
  • 정의 상태:
  • f[i][j]는 길이가 i이고 j로 끝나는 합법적인 서열
  • 을 나타낸다
  • 사고 초기화:
  • f[0]0] = 1

  • 사고 상태 이동 방정식:
  • f[i][j] += f[i-1][k],if (s[i] = ‘D’),k∈[0, j-1];j∈[0,i)
  • f[i][j] += f[i-1][k],if (s[i] = ‘I’), k∈[j+1, i];j∈[0,i), k는 현재 서열의 최대 원소 i
  • 보다 크면 안 된다.
  • 사고 출력:accumulate(f[n][i])
  • class Solution {
    public:
        int numPermsDISequence(string s) {
        	int n=s.size(), mod = 1e9+7, f[n+1][n+1]; memset(f, 0, sizeof f);
        	f[0][0]=1;
        	for (int i=1; i<=n; i++)
    		for (int j=0; j<=i; j++) {
    			if (s[i-1]=='D') for (int k=0; k<j; k++) {
    				f[i][j] = (f[i][j] + f[i-1][k]) % mod;
    			} else for (int k=j; k<=i; k++) {
    				f[i][j] = (f[i][j] + f[i-1][k]) % mod;
    			}
    		}
    		int ans=0;
    		for (int v : f[n]) ans=(ans+v)%mod;
            return ans;
        }
    };
    

    복잡도 분석
  • 시간 복잡도: O(n3)O(n^3)O(n3),
  • 공간 복잡도: O(n2)O(n^2)O(n2),
  • 더 좋은 해법이 있을 거예요. 어서 오세요..

    좋은 웹페이지 즐겨찾기