DPã¨ãã¡ã¢åå帰ã¨ã(2)
Competitive Programming Advent Calendarã§tayama0324ãããç´ æ´ãããè¨äºãæ¸ãã¦ãããã¾ããããªã®ã§èªåãããã«è§¦çºããã¦ã以åæ¸ããè¨äºã®ç¶ããæ¸ãã¦ã¿ã¾ããã以ä¸ã¯tayama0324ããã®è¨äºãèªãã§ãããã¨ãåæã«è©±ããã¾ãã
DPã®ã¡ãªããã¨ã¡ã¢åå帰ã®ã¡ãªãã
åºæ¬çã«ã¯tayama0324ããã触ãã¦ããã¡ãªããã§ã¤ãã¦ããã¨æããã§ãããèªåã¯æ¬¡ã®ãããªã¡ãªãããããã¨èãã¦ãã¾ã(æ¬çããé¢ããã ããªã®ã§ãtayama0324ãããç¥ã£ã¦ããä¸ã§æ¢ãã¦æ¸ããªãã£ã®ã ã¨æãã¾ã)ã
- DPã®ã¡ãªãã
- é åã®åå©ç¨ã§ã¡ã¢ãªãç¯ç´ã§ãããã¨ãããã
- ãã¼ã¿æ§é ã工夫ãã¦ã®é«éåãæ¸ããããã
- ã¡ã¢åå帰ã®ã¡ãªãã
- è©ä¾¡ãé 延çã«è¡ãããã
ã²ã¨ã¤ãã¤èª¬æãã¾ãã
é åã®åå©ç¨
ããã¯é常ã«ããç¥ããã¦ãããã¨ã ã¨æãã¾ããé åã§ã¯ããã¾ãããããã£ããããæ°ãè¨ç®ãã以ä¸ã®ã³ã¼ããã¡ã¢åã§æ¸ãå ´åã«æ¯ã¹ã¦ã¡ã¢ãªãç¯ç´ããã¦ãã¾ãã
int prev1 = 1, prev2 = 1, cur; for(int i=2; i<=n; i++){ cur = prev1 + prev2; prev2 = prev1; prev1 = cur; } printf("fib[n] = %d\n", cur);
ã¡ã¢åã§ã¡ã¢ãªç¯ç´ãããã¨ããã£ã¦ãããªããã¨ã¯ãªããããªæ°ããããã§ããèªç¶ã«ã¯ãªããªãã¨æãã¾ãã
ãã¼ã¿æ§é ã工夫ããé«éå
dp[n] = dp[n-k]+dp[n-k+1]+...+dp[n-1] + f(n)
ã¿ãããªå¼ããã£ãã¨ãã¾ã(ä¾ï¼ColorfulChain)ããããæç´ã«ããã¨O(N*K)ããã£ã¦ãã¾ãã¾ãã
ãããããã¯ãç´¯ç©åãBITã使ããªã©ãã¦ããé«éã«è¨ç®ãããã¨ãã§ãã¾ãããããã¡ã¢åå帰ã§ãããã¨ããã¨çµæ§å¤§å¤ã§ã(äºéå帰ã§æ¸ãã°ã§ãã)ã
ä¼¼ãä¾ã¨ãã¦
dp[n] = min(dp[n-k], dp[n-k+1], ..., dp[n-1]) + f(n)
ã®ãããªãã®ãããã¾ã(ä¾ï¼PrimeCompositeGameè¦ãã°ã¤ã³)ã
ããã¾ãæç´ã«ããã¨O(N*K)ã§ãããdequeã使ã£ããmultiset使ã£ããRMQ使ã£ããããã¨è¨ç®éãè½ã¨ãã¾ãããããã¡ã¢åå帰ã§ã©ããã£ã¦å®ç¾ããã®ãã¯ã¡ãã£ã¨èªåã«ã¯åããã¾ããã
è©ä¾¡ãé 延ç
ããããããªãã¨çµ¶å¯¾è§£ããªãã¨ããç¶æ³ã¯è¦ããã¨ããã¾ããããæ³å®è§£æ³ããå°ãæªãè¨ç®éã ãããã©æåãã¨ãã§é«éåãããéããããã¨ããç¶æ³ã¯çµæ§ããã¾ã(ä¾ãã°ã²ã¼ã æ¨æ¢ç´¢ã§ã¢ã«ãã¡ãã¼ã¿æ³ãããã¨ã)ããããªã¨ãã¯å ¨ã¦ã®ç¶æ ãè©ä¾¡ããå¿ è¦ã®ãªãã¡ã¢åå帰ã®æ¹ã(é¢æ°å¼ã³åºãã®ãªã¼ãã¼ããããèæ ®ãã¦ã)æ©ããªããã¨ãå¤ããããªæ°ããã¾ããå®éã«ã¯ãã¾ãè¦ããã¨ã¯ãªãã§ããã©â¦
ã¡ã¢åå帰ã®ãã ãã
ããã¯å®æã¨ãããåãªãèªåã®ãã ããã®è©±ã§ããèªåã¯ã¡ã¢åå帰ãæ¸ãã¨ãã¯ãªãã¹ããã®æ¸ãæ¹ã§æ¸ã!ã¨ããã®ãåºå®ãããã¨ã«ãã¦ãã¾ãã
type memo[MAX_SIZE]; bool visited[MAX_SIZE]; type rec(state x){ //ã¡ã¢åå¦ç if(visited[x]){ return memo[x]; } visited[x] = true; type& ret = memo[x]; ret = initial_value; //åºåº if( ã»ãã®recãå¼ã³åºãå¿ è¦ããªã ){ return ret = é©åãªå¤; } ... ret ã®æ´æ° ... return ret; }
ã¡ã¢åããã¦ãããã©ããã®ãã§ãã¯
ãã®ããæ¹ã¯å¤§ããåãã¦äºç¨®é¡ã®æµåãããããã§ããä¸ã¤ã¯memoã«çµ¶å¯¾å
¥ãå¾ãªãå¤ãåæåæã«ä»£å
¥ãã¦ããæ¹æ³ãããä¸ã¤ã¯boolé
åã§ãã§ã«è¨ªåæ¸ã¿ã確ãããæ¹æ³ã§ãã
èªåã¯å¾è
ã®æ¸ãæ¹ãæç¨ãã¦ãã¾ããæ大ã®çç±ã¯ãåè
ã®æ¹æ³ãã¨ãã¨ã絶対å
¥ãå¾ãªãå¤ãèãã¦åæåããã®ãé¢åã ããã§ããboolé
åãå©ç¨ããããæ¹ã ã¨ãTopCoderãCodeForcesã®ããã«1ãã¡ã¤ã«1ãã¹ãã±ã¼ã¹ã®ã¨ãæ¯åboolé
åãfalseã§åæåããã¦ããã®ã§ãåæåå¦çãæ¸ããã«ãã¿ã¾ãã
visited[x]ã®æ´æ°ã¿ã¤ãã³ã°ã«ã¤ãã¦ã¯æªã ã«å°ãæ©ãã§ãã¾ã(æ¸ãå¿ãã®å¯è½æ§ã¨ããåéããã¦DAGãããªãã£ãã¨ãã«TLEã«ãããWAã«ãããã©ã£ã¡ãããã®ãã¨ãâ¦)ã
return æã®æ¸ãæ¹
以åã¯åç §å¤æ°ã使ããªã
return memo[x] = ret_value;
ã¨ããæ¸ãæ¹ã ã£ãã®ã§ãããäºã¤ã®çç±ãããã®æ¸ãæ¹ã¯ããªãããã«ãªãã¾ããã
- return æãè¤æ°ããã¨ãããmemo[x][y][z]ã¿ããã«å¤æ¬¡å ã«ãªã£ã¦ããã¨ãæ¸ãã®ãé¢åã
- xãéä¸ã§ãã£ããæ¸ãæãã¦ãã¾ããããããªãã
åºåºã¯ç¹å¥å¦çãã
ãããããã¨ã³ã¼ããåé·ã«ãªã£ã¦ãã¾ãå ´åãããã¾ãããç¹å¥ã«å¦çãã¾ããçç±ã¯ãã£ããæ¸ãå¿ãã¦ãã¾ããã¨ãå¤ãããã§ããã¾ããåºåºã®å¦çã¯ã¡ã¢åã®ãã§ãã¯ããå ã«æ¸ãå ´åãããã¾ã(主ã«ã»ã°ãã©å¯¾ç)ãããã©ã«ãã§ã¡ã¢åå¦çã®å¾ã«ãã£ã¦ããã®ã¯ãçµäºæ¡ä»¶ã®å¤å®ã«ã³ã¹ãããããå ´åãããããã§ãã
ãããã«
ã¾ã è¡åç´¯ä¹ã¨ãé£ç«ä¸æ¬¡æ¹ç¨å¼ã¨ãæã¡åããä»ä¸ããæ¢ç´¢ã¨ãè²ã DP/ã¡ã¢åå帰ã«ä»éããæ¸ããã¿ã¯ããã¾ããããã¯ã¾ããã¤ãã®æ©ä¼ã«ã