timus 1741. Communication Fiend URAL 解题报告 DP+读题

timus   1741. Communication Fiend  URAL 解题报告  DP+读题

题目大意:把一个软件从版本1升级到版本n(求最小的花费),现在网上有很多升级软件,分别能从xi升级到yi; 而且这些软件有的能升级正版,有的能升级到盗版……
具体规则是:
Pirated能将原来的正版或者盗版升级到现在的盗版Pirated;  
Licensed 能将原来的正版升级到现在的正版Licensed ;  
Cracked 能将原来的正版或者盗版升级;  (Cracked 是正版)  但是需要注意的是一旦软件被升级到盗版,以后就只能视作盗版,也就说Cracked 虽然是正版的,但是如果从盗版升级过来就视为盗版,从正版升级过来就是为正版!   这是个小坑!
还有就是初始化的时候注意,最开始的版本是正版的

先根据xi排序,xi相同yi升序排列……   然后转化就好了   dp[i][0/1]表示当前版本是i,0盗版,  1正版……  最小的花费

注意int超了,需要longlong或者__int64……

总结:dp小水题,注意理解题意……

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=40010;
const int M=40010;
long long dp[N][2];
struct Update
{
    int x,y,s;
    char ch[10];
}pro[M];
int n,m;
bool cmp(Update u1,Update u2)
{
    if(u1.x!=u2.x)return u1.x<u2.x;
    return u1.y<u2.y;
}
int main()
{
    cin>>n>>m;

    for(int i=1;i<=m;++i)
    {
        scanf("%d %d %d %s",&pro[i].x,&pro[i].y,&pro[i].s,&pro[i].ch);
    }
    sort(pro+1,pro+m+1,cmp);
    memset(dp,-1,sizeof(dp));
   // dp[1][0]=0;
    dp[1][1]=0;
    for(int i=1;i<=m;++i)
    {
        if(pro[i].ch[0]=='L')
        {
            if ( dp[pro[i].x][1]!=-1&&  (dp[pro[i].y][1]==-1 ||  dp[pro[i].y][1]>dp[pro[i].x][1]+pro[i].s )  )
            {
                dp[pro[i].y][1]=dp[pro[i].x][1]+pro[i].s ;
            }
        }else if(pro[i].ch[0]=='C')
        {
            if (dp[pro[i].x][1]!=-1&&  (dp[pro[i].y][1]==-1||  dp[pro[i].y][1]>dp[pro[i].x][1]+pro[i].s )  )
            {///从合法的转化过来
                dp[pro[i].y][1]=dp[pro[i].x][1]+pro[i].s ;
            }
            if (dp[pro[i].x][0]!=-1&&  (dp[pro[i].y][0]==-1||  dp[pro[i].y][0]>dp[pro[i].x][0]+pro[i].s )  )
            {///从盗版的转化过来
                dp[pro[i].y][0]=dp[pro[i].x][0]+pro[i].s ;
            }
        }else if(pro[i].ch[0]=='P')
        {///当前是不合法的


            if (dp[pro[i].x][0]!=-1&&  (dp[pro[i].y][0]==-1||  dp[pro[i].y][0]>dp[pro[i].x][0]+pro[i].s )  )
            {///从盗版的转化过来
                dp[pro[i].y][0]=dp[pro[i].x][0]+pro[i].s ;
            }


            if (dp[pro[i].x][1]!=-1&&  (dp[pro[i].y][0]==-1||  dp[pro[i].y][0]>dp[pro[i].x][1]+pro[i].s )  )
            {///从合法的转化过来
                dp[pro[i].y][0]=dp[pro[i].x][1]+pro[i].s ;
            }
        }
    }
    if(dp[n][0]==-1&&dp[n][1]==-1)
    {
        cout<<"Offline"<<endl;
    }else
    {
        cout<<"Online"<<endl;
        if(dp[n][0]==-1)cout<<dp[n][1]<<endl;
        else if(dp[n][1]==-1)cout<<dp[n][0]<<endl;
        else cout<<min(dp[n][0],dp[n][1])<<endl;
    }
    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值