当前位置:编程学习 > C/C++ >>

poj 2938 Economic Phone Calls

此题的核心就是选择,按时间顺序进行选择的话,可以发现每次选择只和当前选择的集合中时间最晚的电话有关。

所以可以dp。

令f[i][j]为处理了前i个电话,当前选择的电话中最晚的电话为j时,选择的最少电话数。

对于i而言,如果选择i,则有f[i][i]=min{f[i-1][j]},其中1<=j<i,且由j可以判断出i的正确时间。

同时,如果i是今年的电话,则除了上面的转移,还有f[i][i]=min(f[i][i],f[i-1][0]+1)。

如果不选择i,则有f[i][j]=f[i-1][j]。

考虑到可能有前面没有选择的电话,所以这种情况用0表示。

注意边界,如果i是必须选择的,则f[i][0]=INF,否则f[i][0]=f[i-1][0]。

还要注意,最后一个电话才是最近的电话!!!

【代码】


[cpp] 
#include <iostream> 
#include <cstring> 
#include <string> 
#include <cstdio> 
#include <algorithm> 
using namespace std; 
 
const int N=1003,INF=100000; 
 
struct date 

    int mon,day,h,min; 
    bool operator >=(const date& y) 
    { 
        if (mon>y.mon) return true; 
        if (mon<y.mon) return false; 
        if (day>y.day) return true; 
        if (day<y.day) return false; 
        if (h>y.h) return true; 
        if (h<y.h) return false; 
        if (min>=y.min) return true; 
        else return false; 
    } 
}a[N]; 
 
int f[N][N],y[N]; 
bool v[N]; 
 
int main() 

    int i,j,n,ty,ans; 
    char ch; 
 
    freopen("in","r",stdin); 
    while (1) 
    { 
        scanf("%d\n",&n); 
        if (n==0) break; 
        if (n<=10) 
        { 
            i=0; 
        } 
        for (i=n;i>=1;i--) 
        { 
            scanf("%d:%d:%d:%d %d %c\n",&a[i].mon,&a[i].day,&a[i].h, 
                  &a[i].min,&j,&ch); 
            if (ch=='+') v[i]=true; 
            else v[i]=false; 
        } 
        y[1]=0; 
        for (i=2;i<=n;i++) 
            if (a[i]>=a[i-1]) y[i]=y[i-1]+1; 
            else y[i]=y[i-1]; 
        f[1][1]=1; 
        if (v[1]) f[1][0]=INF; 
        else f[1][0]=0; 
        for (i=2;i<=n;i++) 
            f[1][i]=INF; 
        for (i=2;i<=n;i++) 
        { 
            for (j=1;j<=n;j++) 
                f[i][j]=INF; 
            if (v[i]) f[i][0]=INF; 
            else f[i][0]=f[i-1][0]; 
            if (v[i]) 
            { 
                if (y[i]==0) f[i][i]=min(f[i][i],f[i-1][0]+1); 
                for (j=1;j<i;j++) 
                if (f[i-1][j]<INF) 
                { 
                    if (a[i]>=a[j]) ty=y[j]+1; 
                    else ty=y[j]; 
                    if (ty!=y[i]) continue; 
                    f[i][i]=min(f[i][i],f[i-1][j]+1); 
                } 
            } 
            else 
            { 
                for (j=1;j<=n;j++) 
                    f[i][j]=f[i-1][j]; 
                if (y[i]==0) f[i][i]=min(f[i][i],f[i-1][0]+1); 
                for (j=1;j<i;j++) 
                if (f[i-1][j]<INF) 
                { 
                    if (a[i]>=a[j]) ty=y[j]+1; 
                    else ty=y[j]; 
                    if (ty!=y[i]) continue; 
                    f[i][i]=min(f[i][i],f[i-1][j]+1); 
                } 
            } 
        } 
        ans=INF; 

补充:软件开发 , C++ ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,