POJ1160

来源:互联网 发布:微信中淘宝链接打不开 编辑:程序博客网 时间:2024/05/16 08:07

题目链接

这倒题目对我来说感觉很难。想了很久都没有想到,后来看了一份ppt才敲出了代码。这是那个PPT的链接:PPT链接

这里面讲的很详细,照着它说的推一下就能写出程序了。关于最后一页的优化我没有做,不过我感觉应该不会很难。

下面是我A的代码,效率有点低。以后有兴致了,再试着不参考,写一下优化过的代码,看看自己是不是真的理解了。

/*Source CodeProblem: 1160User: BearoxMemory: 176KTime: 313MSLanguage: C++Result: AcceptedSource Code*/#include<stdio.h>int const N = 310;int const M = 1111111;int v, p;int f[N][35];int d[N], _min;int cal(int ti, int tj) //求ti,tj中只有一个邮局的距离{int i, k = 0;if(ti == tj) return 0;if((tj - ti) & 1){  //有奇数个点,邮局在中间for(i = 0; i <= ((tj - ti) >> 1); ++i)k += d[tj - i] - d[ti + i];return k;}for(i = 0; i < ((tj - ti) >> 1) + 1; ++i)k += d[tj - i] - d[i + ti];  ////偶数个点return k;}int min(int a, int b){return a < b? a : b;}int main(){int i, j, k;while(scanf("%d%d", &v, &p) != EOF){for(i = 1; i <= v; ++i){scanf("%d", d + i);f[i][1] = 0;/*-------求只有一个邮局时候的距离------*///i是奇数的时候 邮局是中间的那个 偶数时中间两个都一样for(j = 1; j < i / 2 + 1; ++j)f[i][1] += d[i - j + 1] - d[j];}for(k = 2; k <= p; ++k){ //邮局的个数逐渐增加f[k][k] = 0; //前k个点建立k个邮局,距离和为0for(i = k + 1; i <= v; ++i){//前i个点建立k个邮局的最小距离和_min = M;for(j = k; j <= i; ++j)//前j-1个点用k-1个邮局,枚举j_min = min(f[j - 1][k - 1] + cal(j, i), _min);f[i][k] = _min;}}printf("%d\n", f[v][p]);}return 0;}


原创粉丝点击