第十届省赛 D题

来源:互联网 发布:邮政网络培训学院登录 编辑:程序博客网 时间:2024/06/05 01:19

思路:当时比赛知道是dp题推了好久没推出来。~....~.比赛之后搜了一下别人的解题思路。。。。原来还是自己动态规划学的太弱了。

题意是说:有n个项目,每个项目都有一个难度系数,每一个技术人员至少做k个项目,对于每个技术人员的酬金是c+(做的所有项目的最大难度系数-最小难度系数)的平方。我们可以知道一个区间中的差越小,相对的情况下(技术人员的个数不固定)公司付出的钱越少。我们可以假设一个技术人员可以做k个,k+1,k+2.........

枚举每一个符合条件的区间得到一个二维数组dp[i][j],表示做i到j区间的酬金为dp[i][j];

然后从满足的区间中找到dp[1][n]的最小值。

动态转移方程:

         dp[i][j]=min( dp[i][j] , dp[i][k] + dp[k+1][j])

我的code:

#include<stdio.h>#include<iostream>#include<algorithm>#include<memory.h>#define inf 0x3f3f3f3f//区间dpusing namespace std;int main(){    int n,k,c;    while(scanf("%d%d%d",&n,&k,&c)!=EOF)    {        int a[105],dp[105][105],i,j;        memset(dp,inf,sizeof(dp));//初始化为无穷大        for(i=1; i<=n; i++) //输入n个项目的难度        {            scanf("%d",&a[i]);        }        sort(a+1,a+n+1);        for(i=1; i<=n; i++) //求出每一个长度大于等于区间的数        {            for(j=i+k-1; j<=n; j++)            {                dp[i][j]=c+(a[j]-a[i])*(a[j]-a[i]);            }        }       for(i=1;i<=n;i++)        for(j=1;j<=n;j++)         for(k=i;k<j;k++)         {             dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]);         }       cout<<dp[1][n]<<endl;    }}
参考题解:点击打开原文