题意:
一些有长度l和重量w的木棍要装在机器上,如果前一个木棍长度和重量均小于等于当前木棍,装上机器不耗时,否则时间+1,问全装上最少时间。
要点:
可以用贪心或DP,贪心就是先按长度从小到大排好,再根据重量,用一个d数组标记是否用过,从一根木棍出发,往后找重量大于等于它的木棍,将它的d标记为1,再以这个新木棍为起点再往后找,遍历一遍后再从d为0的木棍出发,看能遍历几次就是最小时间。
贪心:
15583101 | Seasonal | 1065 | Accepted | 224K | 16MS | C++ | 822B | 2016-06-02 15:32:11 |
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{int l, w;
}a[5005];
int d[5005];bool cmp(node a, node b)
{if (a.l == b.l)return a.w < b.w;return a.l < b.l;
}int main()
{int t,n,i;scanf("%d", &t);while (t--){scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d%d", &a[i].l, &a[i].w);sort(a, a + n, cmp);memset(d, 0, sizeof(d));int ans = 0;while (1){bool flag = true;int temp;for (i = 0; i < n; i++)if (d[i] == 0){temp = i;d[i] = 1;flag = false;ans++;break;}if (flag)break;for (i = 0; i < n; i++){if (!d[i] && a[temp].l <= a[i].l&&a[temp].w <= a[i].w){temp = i;d[i] = 1;}}}printf("%d\n", ans);}return 0;
}
DP(偏序定理):
这题用DP需要用到偏序定理,看不太懂,应用到这题就是,按l从小到大排好后,求有几个最大不下降子序列,那么这里运用偏序定理可以知道,有几个最大不下降子序列等于最大下降子序列中的元素个数,具体证明是用鸽笼原理,看的半懂不懂的,下学期学一下离散数学再看看吧。
偏序定理: 点击打开链接
鸽笼原理证明: 点击打开链接
15583207 | Seasonal | 1065 | Accepted | 224K | 110MS | C++ | 658B | 2016-06-02 15:52:25 |
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<algorithm>
using namespace std;
struct node
{int l, w;
}a[5005];
int dp[5005];bool cmp(node a, node b)
{if (a.l == b.l)return a.w < b.w;return a.l < b.l;
}int main()
{int t,n,i,j;scanf("%d", &t);while (t--){scanf("%d", &n);for (i = 0; i < n; i++)scanf("%d%d", &a[i].l, &a[i].w);sort(a, a + n, cmp);for (i = 0; i < n; i++)dp[i] = 1;for (i = 0; i < n; i++)for (j = 0; j < i; j++)if (a[i].w < a[j].w)//求最长下降序列dp[i] = max(dp[i], dp[j] + 1);int ans = -1;for (i = 0; i < n; i++)ans = max(ans, dp[i]);printf("%d\n", ans);}return 0;
}