您的位置:首页 > 其它

HDU 1025 Constructing Roads In JGShining's Kingdom(LIS最长上升子序列)

2016-06-20 15:25 537 查看
**题意:**2n个城市中有n个属于资源贫困型另外n个属于资源富裕型,资源贫困型的城市只缺少一种资源且缺少的资源各不相同,资源富裕的城市只产出一种资源且产出的资源也各不相同。给出了部分贫困城市的需求,需求表示了贫困城市向富裕城市进口资源,为了运送资源要在资源贫困和富裕的两城市间修路且道路不能出现交叉,问最多修多少条路?

分析:一道求最长上升子序列的题目,二维数据先将第一维从小到大排序,再找第二维数据的最长上升子序列,从而保证了所修道路之间不会交叉。需要特别注意的是结果的输出。一条路与多条路输出的结果不同。

代码:(二分查找AC)

#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;

struct node {
int p, r;
bool operator<(const node &a)const {
return p < a.p;
}
};

node TestCase[500005];
int dp[500005];

int main() {
int n, Case = 0;
while (scanf_s("%d", &n) != EOF) {
for (int i = 0; i < n; ++i) {
scanf("%d%d", &TestCase[i].p, &TestCase[i].r);
}

sort(TestCase, TestCase + n);

memset(dp, 0, sizeof(dp));

int top = 0;
for (int i = 0; i < n; ++i) {//最长上升子序列1
if (dp[top] < TestCase[i].r) {
dp[++top] = TestCase[i].r;
}
else {
int low = 1, high = top;
while (low < high) {
int mid = (low + high) >> 1;
if (dp[mid] < TestCase[i].r) {
low = mid + 1;
}
else {
high = mid;
}
}
dp[high] = TestCase[i].r;
}
}
if (top == 1) {
printf("Case %d:\nMy king, at most %d road can be built.\n\n", ++Case, top);
}
else {
printf("Case %d:\nMy king, at most %d roads can be built.\n\n", ++Case, top);
}

}
return 0;
}


#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;

struct node {
int p, r;
bool operator<(const node &a)const {
return p < a.p;
}
};

node TestCase[500005];
int dp[500005];

int main() {
int n, Case = 0;
while (scanf_s("%d", &n) != EOF) {
for (int i = 0; i < n; ++i) {
scanf("%d%d", &TestCase[i].p, &TestCase[i].r);
}

sort(TestCase, TestCase + n);

memset(dp, 0, sizeof(dp));

int top = 0;
for (int i = 1; i <= n; i++)//最长上升子序列2
{
if (TestCase[i].r>dp[top]){//如果a[i]>栈顶部元素,则压栈
dp[++top] = TestCase[i].r;
}
else//如果a[i]不大于栈顶部元素,则二分查找第一个比a[i]大的元素
{
int low = 1, high = top;
while (low <= high)
{
int mid = (low + high) >> 1;
if (TestCase[i].r>dp[mid])
{
low = mid + 1;
}
else
high = mid - 1;
}
dp[low] = TestCase[i].r;//替换a[i]
}
}

if (top == 1) {
printf("Case %d:\nMy king, at most %d road can be built.\n\n", ++Case, top);
}
else {
printf("Case %d:\nMy king, at most %d roads can be built.\n\n", ++Case, top);
}
}
return 0;
}


代码:(n^2超时)

#include<iostream>
#include<algorithm>
#include<cstdio>

using namespace std;

struct node {
int p, r;
bool operator<(const node &a)const {
return p < a.p;
}
};

node TestCase[500005];
int dp[500005];

int main() {
int n, Case = 0;
while (scanf_s("%d", &n) != EOF) {
for (int i = 0; i < n; ++i) {
scanf("%d%d", &TestCase[i].p, &TestCase[i].r);
}

sort(TestCase, TestCase + n);

memset(dp, 0, sizeof(dp));

for (int i = 0; i < n; ++i) {//n^2方法超时
dp[i] = 1;
for (int j = 0; j < i; ++j) {
if (TestCase[i].r > TestCase[j].r) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
}
int ans = 0;
for (int i = 0; i < n; ++i) {
ans = max(ans, dp[i]);
}

if (ans == 1) {
printf("Case %d:\nMy king, at most %d road can be built.\n\n", ++Case, ans);
}
else {
printf("Case %d:\nMy king, at most %d roads can be built.\n\n", ++Case, ans);
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: