HYSBZ 3996 线性代数

HYSBZ 3996 线性代数

题目描述:

输入一个 N×N 的矩阵 B 和一个 1×N 的列向量 C ,求一个 01 矩阵 A ,使得 (A×BC)×AT 最大(可以证明这是一个 1×1 的矩阵)。输出那个最大的值。

题解:

(A×BC)×AT=A×B×ATC×AT=ijA1,jA1,iBj,iiA1,iC1,i

模型转化,假设有 N 个物品, A1,i 表示第 i 个选不选,选的话去要付出 C1,i 的代价,但如果两个物品 i j 都选就会得到 Bi,j 的收益,问最大收益和是多少。

于是就变成了网络流经典问题。算了一下大概有 3105 个点, 2106 条边,我也不知道为什么能跑的过去……

题目链接: vjudge 原网站

代码:


#include <queue>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXM = 300007;
const int MAXG = 2000007;

#define encode(i, j) (N * (i) + (j))

#define S (0)
#define T (N * N + N + 1)

const int INF = 0x3f3f3f3f;

static struct
{
    int v, w, next;
} edge[MAXG];
static int N, G, sum, head[MAXM], dist[MAXM];

inline void add_edge(int u, int v, int w)
{
    edge[G].v = v; edge[G].w = w; edge[G].next = head[u]; head[u] = G++;
    edge[G].v = u; edge[G].w = 0; edge[G].next = head[v]; head[v] = G++;
}

inline bool bfs(void)
{
    queue<int> Q;
    memset(dist, 0, sizeof(dist));
    Q.push(S); dist[S] = 1;
    while (!Q.empty())
    {
        int x = Q.front(); Q.pop();
        for (int i = head[x]; ~i; i = edge[i].next)
            if (edge[i].w && !dist[edge[i].v])
                Q.push(edge[i].v), dist[edge[i].v] = dist[x] + 1;
    }
    return dist[T];
}

int dfs(int x, int f)
{
    if (x == T) return f;
    int r = 0;
    for (int i = head[x]; ~i && r < f; i = edge[i].next)
        if (edge[i].w && dist[edge[i].v] == dist[x] + 1)
        {
            int delta = dfs(edge[i].v, min(f - r, edge[i].w));
            r += delta;
            edge[i].w -= delta; edge[i^1].w += delta;
        }
    if (!r) dist[x] = -1;
    return r;
}

int main()
{
    memset(head, -1, sizeof(head));
    scanf("%d", &N);
    for (int i = 1; i <= N; i++)
        for (int j = 1, x; j <= N; j++)
        {
            scanf("%d", &x);
            sum += x;
            add_edge(S, encode(i, j), x);
            add_edge(encode(i, j), i, INF);
            add_edge(encode(i, j), j, INF);
        }
    for (int i = 1, x; i <= N; i++)
        scanf("%d", &x), add_edge(i, T, x);
    while (bfs())
        sum -= dfs(S, INF);
    printf("%d\n", sum);
    return 0;
}

提交记录(AC / Total = 1 / 2):

Run IDRemote Run IDTime(ms)Memory(kb)ResultSubmit Time
87381231991020819836RE2017-04-11 08:55:59
87381471991032158827556AC2017-04-11 09:02:30
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,你可以参考以下示例代码实现Java销售额查询和营业额统计: ```java import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class SalesStatistics { private Map<String, Double> salesData = new HashMap<>(); public SalesStatistics() { // 初始化销售数据 salesData.put("2021-01-01", 1000.0); salesData.put("2021-01-02", 1500.0); salesData.put("2021-01-03", 2000.0); salesData.put("2021-01-04", 1200.0); salesData.put("2021-01-05", 1800.0); } // 查询指定日期的销售额 public double getSalesByDate(String date) { if (salesData.containsKey(date)) { return salesData.get(date); } else { return 0.0; } } // 统计指定日期范围内的营业额 public double getTotalSales(String startDate, String endDate) { double totalSales = 0.0; for (String date : salesData.keySet()) { if (date.compareTo(startDate) >= 0 && date.compareTo(endDate) <= 0) { totalSales += salesData.get(date); } } return totalSales; } // 获取所有销售日期 public List<String> getAllSalesDates() { return new ArrayList<>(salesData.keySet()); } } ``` 使用示例: ```java public static void main(String[] args) { SalesStatistics salesStatistics = new SalesStatistics(); // 查询指定日期的销售额 double sales = salesStatistics.getSalesByDate("2021-01-02"); System.out.println("2021-01-02的销售额为:" + sales); // 统计指定日期范围内的营业额 double totalSales = salesStatistics.getTotalSales("2021-01-02", "2021-01-04"); System.out.println("2021-01-02到2021-01-04的营业额为:" + totalSales); // 获取所有销售日期 List<String> salesDates = salesStatistics.getAllSalesDates(); System.out.println("所有销售日期为:" + salesDates); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值