程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 2938 Economic Phone Calls

poj 2938 Economic Phone Calls

編輯:C++入門知識

此題的核心就是選擇,按時間順序進行選擇的話,可以發現每次選擇只和當前選擇的集合中時間最晚的電話有關。

所以可以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; 
        for (i=1;i<=n;i++) 
            ans=min(ans,f[n][i]); 
        if (ans>=INF) ans=n; 
        printf("%d\n",ans); 
    } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved