HDU 5492 Find a path DP —— 2015 ACM-ICPC Asia Regional Hefei Online

原题见HDU 5492
给一个N*M的矩阵,从(1,1)到(N,M)经过的格点分值分别为 Ai ,(路径只能向右或向下走,共N+M-1步)。求各种路径中最小的 (N+M1)N+M1i=1(AiAavg)2 .其中 AavgAi
N,M分别为1~30的整数, Ai 为不超过30的整数。

首先对表达式进行化简: N+M1i=1 先记为

(N+M1)(AiAavg)2
=(N+M1)(A2i+A2avg2AiAavg)

其中 Aavg=1N+M1Ai ,则 2AiAavg=2(N+M1)A2avg
=(N+M1)[(A2i)(N+M1)A2avg]
=(N+M1)A2i(Ai)2
a=A2i,b=Ai 则只要在图上的格点p[i][j]存下每个b对应的最大的a值并向右下角DP即可。其中b为不超过30*(30+30)=1800的数,故在p[i][j]上开一个大小为2000的数组c[2000]即足够存下所有状态b.使得c[b]=min{a}.

附code:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <queue>
#include <algorithm>
#include <cmath>
using namespace std;
struct node
{
    int v, a, b, c[2000];
}p[50][50];
int fac(int x)
{
    return x*x;
}
int main()
{
    int T, o = 0;
    scanf("%d", &T);
    while(T--)
    {
        int n, m;
        scanf("%d%d", &n, &m);
        memset(p, 0, sizeof(p));
        for(int i = 1;i <= n;i++)
            for(int j = 1;j <= m;j++)
                scanf("%d", &p[i][j].v);
        p[1][1].a = fac(p[1][1].v);
        p[1][1].b = p[1][1].v;
        p[1][1].c[p[1][1].v] = fac(p[1][1].v);
        for(int j = 2;j <= m;j++)
        {
            p[1][j].a = p[1][j-1].a+fac(p[1][j].v);
            p[1][j].b = p[1][j-1].b+p[1][j].v;
            p[1][j].c[p[1][j].b] = p[1][j].a;
        }
        for(int i = 2;i <= n;i++)
        {
            p[i][1].a = p[i-1][1].a+fac(p[i][1].v);
            p[i][1].b = p[i-1][1].b+p[i][1].v;
            p[i][1].c[p[i][1].b] = p[i][1].a;
        }
        for(int i = 2;i <= n;i++)
            for(int j = 2;j <= m;j++)
                for(int k = 0;k < 2000;k++)
                {
                    if(p[i][j-1].c[k])
                    {
                        int f = k+p[i][j].v;
                        if(p[i][j].c[f])
                            p[i][j].c[f] = min(p[i][j].c[f], p[i][j-1].c[k]+fac(p[i][j].v));
                        else
                            p[i][j].c[f] = p[i][j-1].c[k]+fac(p[i][j].v);
                    }
                    if(p[i-1][j].c[k])
                    {
                        int f = k+p[i][j].v;
                        if(p[i][j].c[f])
                            p[i][j].c[f] = min(p[i][j].c[f], p[i-1][j].c[k]+fac(p[i][j].v));
                        else
                            p[i][j].c[f] = p[i-1][j].c[k]+fac(p[i][j].v);
                    }
                }
        int ans = 1000000000;
        for(int i = 0;i < 2000;i++)
            if(p[n][m].c[i])
                ans = min(ans, (n+m-1)*p[n][m].c[i]-fac(i));
        printf("Case #%d: %d\n", ++o, ans);
    }
    return 0;
}
非常抱歉,我在给出的代码中错误地提及了 `VirtualCamera` 类。事实上,SharpDX.MediaFoundation 库本身并没有提供直接创建虚拟摄像头的功能。要创建虚拟摄像头并将视频流推送到它,你可能需要使用第三方库或工具,例如虚拟摄像头驱动程序或框架。 一种常见的选择是使用 Dshow 系统库。你可以使用 DirectShow 库来创建虚拟摄像头,并使用 SharpDX.MediaFoundation 与 DirectShow 进行交互。以下是一个基本的示例代码,演示了如何将视频流推送到虚拟摄像头: ```csharp using System; using DirectShowLib; using SharpDX.MediaFoundation; class Program { static void Main() { // 加载虚拟摄像头驱动程序 var virtualCamera = LoadVirtualCameraDriver(); if (virtualCamera == null) { Console.WriteLine("无法加载虚拟摄像头驱动程序!"); return; } // 创建源视频文件的读取器 using (var sourceReader = CreateSourceReader("path/to/source/video.mp4")) { // 获取第一个视频流的格式 var mediaType = GetVideoMediaType(sourceReader, 0); // 将视频流推送到虚拟摄像头 PushVideoToVirtualCamera(sourceReader, virtualCamera, mediaType); Console.WriteLine("视频流已成功推送到虚拟摄像头!按任意键停止..."); Console.ReadKey(); } // 卸载虚拟摄像头驱动程序 UnloadVirtualCameraDriver(virtualCamera); } static IBaseFilter LoadVirtualCameraDriver() { // TODO: 加载虚拟摄像头驱动程序的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来加载虚拟摄像头驱动程序并获取其 IBaseFilter 对象 return null; } static void UnloadVirtualCameraDriver(IBaseFilter virtualCamera) { // TODO: 卸载虚拟摄像头驱动程序的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来卸载虚拟摄像头驱动程序 } static SourceReader CreateSourceReader(string videoFilePath) { var attributes = new MediaAttributes(); attributes.Set(CaptureDeviceAttributeKeys.SourceType, CaptureDeviceAttributeKeys.SourceTypeVideoCapture.Guid); var sourceReader = new SourceReader(videoFilePath, attributes); return sourceReader; } static MediaType GetVideoMediaType(SourceReader sourceReader, int streamIndex) { var mediaType = sourceReader.GetNativeMediaType(streamIndex, 0); return mediaType; } static void PushVideoToVirtualCamera(SourceReader sourceReader, IBaseFilter virtualCamera, MediaType mediaType) { var sample = new MediaSample(); // TODO: 将视频流推送到虚拟摄像头的代码 // 可以使用 DirectShowLib 库中的 FilterGraph 或其他相关类来将视频流推送到虚拟摄像头 } } ``` 注意,上述代码中的 `LoadVirtualCameraDriver` 和 `UnloadVirtualCameraDriver` 方法是示例代码,需要根据你使用的虚拟摄像头驱动程序进行实际实现。你可以使用 DirectShowLib 库中的 FilterGraph 类或其他相关类来加载和卸载虚拟摄像头驱动程序。 希望这次提供的代码能够帮助到你,如果你有任何进一步的问题随时提问。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值