光辉 的个人资料胡言乱语照片日志列表更多 ![]() | 帮助 |
|
2006/11/28 安全套的材质分类以下来自小百合http://bbs.nju.edu.cn
现在市场上的tt大概有三类:橡胶材质的、羊肠内组织(“表皮”)材质的和聚亚安酯材 质的。不过,其中由动物表皮制成的tt允许爱滋病毒、疱疹、肝炎病原体等通过,不能称 为“安全套”;而聚亚安酯制成的更薄,更有感觉,触感比橡胶材质的好很多,不过是比 较贵哦! 2006/11/24 子序列求和问题:已知一个整数数组A,求一个最小的正整数M,使得M等于数组A的一个子序列的和。
第一步:
设数组A的长度为n,令数组sum[1..n]为以下值:
sum[1] = A[1];
sum[2] = A[1] + A[2] = sum[1] + A[2];
......
sum[i] = A[1] + A[2] + ... + A[i] = sum[i-1] + A[i];
......
sum[n] = A[1] + A[2] + ... + A[n] = sum[n-1] + A[n];
这一步的时间复杂度为O(n)。
第二步:
对数组sum[1..n]进行快速排序,使该数组按升序排列。
如果sum[a] == sum[b], 按以下规则排序:
如果 a < b,则 sum[b] 排在 sum[a] 前面。反之,sum[a] 排在 sum[b] 前面。
这一步的时间复杂度为O(nlogn)。
第三步:
设排序后的sum数组为:
sum[a1], sum[a2], ...... sum[an]
按如下方式遍历该数组:
i = [1..n]。
1) 如果 sum[ai] > 0 并且 sum[ai] < min, 令 min = sum[ai]。
2) 如果 0 < sum[a(i+1)] - sum[ai] < min 并且 a(i+1) > ai,令 min = sum[a(i+1)] - sum[ai]。
注意边界情况。
最后求得的min为该问题的解。
这一步的时间复杂度为O(n)。
//
该算法总的时间复杂度为O(nlogn)。
//
详细代码:
struct subsum
{ int value; int length; }; int minsubsum(int A[], int length) { int i; int min = 0; struct subsum *sum = new struct subsum[length+1]; sum[0].value = 0; sum[0].length = length+1; for(i=1; i<=length; i++) { sum[i].value = sum[i-1].value + A[i-1]; sum[i].length = i; } qsort(sum+1, length, sizeof(struct subsum), compare); for(i=1; i<=length; i++) { if (sum[i].value > 0) { if (min == 0) min = sum[i].value; else if (sum[i].value < min) min = sum[i].value; } if (sum[i].value != sum[i-1].value && sum[i].length > sum[i-1].length) { if (min == 0) min = sum[i].value - sum[i-1].value; else if (sum[i].value-sum[i-1].value < min) min = sum[i].value - sum[i-1].value; } } delete [] sum; return min; } int compare(const void *a, const void *b) { if (((struct subsum*)a)->value == ((struct subsum*)b)->value) return ((struct subsum*)b)->length - ((struct subsum*)a)->length; else return ((struct subsum*)a)->value - ((struct subsum*)b)->value; } |
|
|