1611. Decimation

http://acm.timus.ru/problem.aspx?space=1&num=1611

DP 递推

显然这个题是可能有多组解的   求最优解+记录路径即可

当 i 个 conductors 和 j 个 dodgers 时 最后的人可能是 conductor 也可能是 dodger 枚举这两种情况最优即可

代码及其注释:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <string>

#include <queue>

#include <vector>

#include <algorithm>



#define LL long long

//#pragma comment(linker, "/STACK:1024000000,1024000000")

using namespace std;

const int N=10005;

const int M=55;

int ans[N][M];//i 个conductors  和 j 个dodgers 时的最优解

int fx[N][M];//最优解的向前指针

int fy[N][M];

string s;//输入

void dfs(int l1,int l2)//答案输出

{

    if(fy[l1][l2]>=1)

    dfs(fx[l1][l2],fy[l1][l2]);

    if(fy[l1][l2]==l2-1)

    {cout<<" "<<(l1+l2);}

}

int main()

{

    //freopen("data.txt","r",stdin);

    int n,m;

    while(cin>>n>>m)

    {

        cin>>s;

        for(int j=0;j<=m;++j)

        {ans[0][j]=j/10;fx[0][j]=0;fy[0][j]=j-1;}//初始化

        for(int i=1;i<=n;++i)

        {

            ans[i][0]=ans[i-1][0];//初始化

            if(i%10==0&&s[i-1]=='1')

            ++ans[i][0];

        }

        for(int i=1;i<=n;++i)

        {

            for(int j=1;j<=m;++j)

            {

                //第一种是最后一个是conductor 的情况

                ans[i][j]=ans[i-1][j];

                if(s[i-1]=='1'&&(i+j)%10==0)

                ++ans[i][j];

                fx[i][j]=i-1;

                fy[i][j]=j;

                //第二种情况是最后是dodger 的情况

                int temp=((i+j)%10)?0:1;

                if(ans[i][j-1]+temp<ans[i][j])

                {

                    ans[i][j]=ans[i][j-1]+temp;

                    fx[i][j]=i;

                    fy[i][j]=j-1;

                }

            }

        }

        int l2=0;

        for(int j=1;j<=m;++j)

        if(ans[n][j]<ans[n][l2])

        l2=j;

        cout<<ans[n][l2]<<endl;

        cout<<l2;

        dfs(n,l2);

    }

    return 0;

}



 

 

你可能感兴趣的:(mat)