UVa:10271 Chopsticks

来源:互联网 发布:泸沽湖摩梭人骗局 知乎 编辑:程序博客网 时间:2024/05/29 19:26

 

想了一晚上加一上午,总算是给做出来了,还是1Y.

 

还是跟前面的几道题有些相似。

dp[i][j]表示前i个客人使用第j支与第j-1支筷子作为短筷子时的烂度。

很明显三元组中两只短筷子一定是相邻的,长筷子则不一定。

用降序做会比较好。

p[i][j]表示dp[i][j]对应状态可使用的长筷子。

 

状态转移方程:

 如果p[i-1][j-2]>1则说明可以使用第j支与第j-1支筷子作为短筷子 此时dp[i][j]=min(dp[i-1][j-2]+badness,dp[i-1][j])分别表示使用和不使用

如果不能,则dp[i][j]=dp[i-1][j] 不使用第j支与第j-1支筷子作为短筷子

 

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define INF 0x7f7f7f7fusing namespace std;int ch[5005];int dp[1005][5005];int p[1005][5005];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int K,N;        scanf("%d%d",&K,&N);        K=K+8;        memset(dp,0,sizeof(dp));        memset(p,0,sizeof(p));        for(int i=N; i>0; --i)            scanf("%d",&ch[i]);        for(int i=1; i<=N; ++i)            p[0][i]=i;        for(int i=1; i<=K; ++i)        {            for(int j=1; j<=N; ++j)            {                if(j<3*i-1)                {                    dp[i][j]=INF;                    p[i][j]=j;                }                else                {                    if(p[i-1][j-2]>0)                    {                        int ld=(ch[j]-ch[j-1])*(ch[j]-ch[j-1]);                        if(dp[i-1][j-2]+ld<dp[i][j-1])                        {                            dp[i][j]=dp[i-1][j-2]+ld;                            p[i][j]=p[i-1][j-2]-1;                        }                        else                        {                            dp[i][j]=dp[i][j-1];                            p[i][j]=p[i][j-1]+1;                        }                    }                    else                    {                        dp[i][j]=dp[i][j-1];                        p[i][j]=p[i][j-1]+1;                    }                }            }        }        printf("%d\n",dp[K][N]);    }    return 0;}


 

 

网上的题解和我的思路基本一致,不过没有用p[][]这个数组。代码修改后如下。

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#define INF 0x7f7f7f7fusing namespace std;int ch[5005];int dp[1005][5005];int main(){    int T;    scanf("%d",&T);    while(T--)    {        int K,N;        scanf("%d%d",&K,&N);        K=K+8;        memset(dp,0,sizeof(dp));        for(int i=N; i>0; --i)            scanf("%d",&ch[i]);        for(int i=1; i<=K; ++i)        {            for(int j=1; j<=N; ++j)            {                if(j<3*i)                    dp[i][j]=INF;                else                {                        int ld=(ch[j]-ch[j-1])*(ch[j]-ch[j-1]);                        dp[i][j]=min(dp[i-1][j-2]+ld,dp[i][j-1]);                }            }        }        printf("%d\n",dp[K][N]);    }    return 0;}


 

原创粉丝点击