codeforces 269B Greenhouse Effect (贪心+dp)

来源:互联网 发布:p鼻子的软件 编辑:程序博客网 时间:2024/05/22 06:45

题解:

给出n棵树,每颗树都属于某种品种,品种按照1-m标号。现在给出了每棵树的品种和位置,问如何用最小的移动次数使得这n棵树的品种按照递增的序号牌号。

题解:

一开像这样做:dp[i][2] dp[i][0]表示以i这棵树前面树的品种序号比他大的个数,dp[i][1]相反。然后从1-n找出dp[i][1]+dp[i][0]的最小值,但是想了下第三个测试实例,果然推翻。

突然灵光一动发现一个规律,用贪心来分析发现,只要尽量让序列中品种数成上升的个数最多,那么就是找着序列中非递减子序列(可以有相同的),然后n-这个最长的非递减子序列就是我们要一动树的个数!!1a

#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef long long lld;const int oo=0x3f3f3f3f;const lld OO=1e18;const int Mod=1000000007 ;const int maxn=5000+5;int dp[maxn];struct Tree{    int spe;    double pos;}a[maxn];bool cmp(Tree t1,Tree t2){    return t1.pos<t2.pos;}int main(){    int n,m,ans;    while(scanf("%d %d",&n,&m)!=EOF)    {        for(int i=1;i<=n;i++)            scanf("%d %lf",&a[i].spe,&a[i].pos);        sort(a+1,a+1+n,cmp);        memset(dp,0,sizeof dp);        a[0].spe=-oo;        for(int i=1;i<=n;i++)        {            for(int j=0;j<i;j++)            {                if(a[j].spe<=a[i].spe&&dp[j]+1>dp[i])                    dp[i]=dp[j]+1;            }        }        ans=oo;        for(int i=1;i<=n;i++)            ans=min(ans,n-dp[i]);        printf("%d\n",ans);    }    return 0;}/**3 22 11 2.01 3.1003 31 5.02 5.53 6.06 31 14.2842352 17.9213821 20.3281723 20.8423311 25.7901451 27.204125*/




0 0
原创粉丝点击