动态规划——Dining Cows

来源:互联网 发布:盘点2016年网络流行语 编辑:程序博客网 时间:2024/06/05 21:16

The cows are so very silly about their dinner partners. They have organized themselves into three groups (conveniently numbered 1, 2, and 3) that insist upon dining together. The trouble starts when they line up at the barn to enter the feeding area.

Each cow i carries with her a small card upon which is engraved Di (1 ≤ Di ≤ 3) indicating her dining group membership. The entire set of N (1 ≤ N ≤ 30,000) cows has lined up for dinner but it's easy for anyone to see that they are not grouped by their dinner-partner cards.

FJ's job is not so difficult. He just walks down the line of cows changing their dinner partner assignment by marking out the old number and writing in a new one. By doing so, he creates groups of cows like 111222333 or 333222111 where the cows' dining groups are sorted in either ascending or descending order by their dinner cards.

FJ is just as lazy as the next fellow. He's curious: what is the absolute mminimum number of cards he must change to create a proper grouping of dining partners? He must only change card numbers and must not rearrange the cows standing in line.

Input

* Line 1: A single integer: N
* Lines 2..N+1: Line i describes the i-th cow's current dining group with a single integer: Di

Output

* Line 1: A single integer representing the minimum number of changes that must be made so that the final sequence of cows is sorted in either ascending or descending order

Sample Input
513211
Sample Output
1

题意:第一行给个n代表接下来有n个数字, 每个数字一行,每次可以改变一个数字,但是改的范围是1~3,求最少要多少次才能使整个序列有序(非递减或非递增)

思路:先正着来一遍dp得到然后再把数组倒置来一遍dp,综合两个得到ans。详见代码。


#include <cstdio>#include <cstring>#include <algorithm>#include <iostream>#define INF 0x3f3f3f3fusing namespace std;int dp[30010][4];   //dp[i][j]表示第i个数为j时的最小次数int a[30010];int n;int ans;void fun(){    for(int i=1; i<=n; i++)        for(int j=1; j<=3; j++)        {            if(a[i]==j)                                                  //如果第i个数等于j            {                                                               //则不用修改                dp[i][j]=INF;                                          //dp[i][j]等于dp[i-1]中最小的                for(int k=j; k>=1; k--)                                                  dp[i][j]=min(dp[i][j], dp[i-1][k]);            }            else                                       //如果不等,则需要修改                dp[i][j]=dp[i-1][j]+1;                    }}int main(){    while(~scanf("%d", &n))    {        memset(dp, 0, sizeof(dp));        memset(a, 0, sizeof(a));        for(int i=1; i<=n; i++)            scanf("%d", &a[i]);        fun();        ans=min(dp[n][1], dp[n][2]);        ans=min(dp[n][3], ans);        for(int i=1; i<=n/2; i++)    //将数组倒置        {            int t=a[i];            a[i]=a[n-i+1];            a[n-i+1]=t;        }        fun();        ans=min(ans, dp[n][1]);        ans=min(ans, dp[n][2]);        ans=min(ans, dp[n][3]);        printf("%d\n", ans);    }    return 0;}


原创粉丝点击